API v2 Changelog
All notable changes to the Interchange API v2 are documented here.2.190.0 — June 23, 2026 at 6:09 PM UTC
- Bulk creative updates can now set
format_idandtarget_format_ids, not justclick_url. This lets you retype many creatives to a sales agent’s required format (for example OpenAdsdisplay_300x250_nongenerative) in a single call, matched by size, instead of editing each creative one at a time. - Campaign execution now returns a clear, actionable error naming the affected product when a selected product cannot be funded within the campaign’s remaining media budget, instead of failing later with an internal database error. Raise the campaign budget or reduce other media buys, then re-run execute.
2.189.1 — June 23, 2026 at 4:46 PM UTC
- Fixed available account discovery for adapter storefronts after connecting buyer-managed provider accounts.
- Fixed creative approval and assignment handling across the campaign → media buy → storefront flow:
- Creative approval status syncing back from sales agents: operator approvals (delivered as an “updated/approved” review verdict) were being recorded as still-pending and triggering spurious “changes requested” notifications; the per-agent approval status was also written in a different case than the readers expected, so approved creatives could read back as unregistered. Creative status is now derived across every sales agent a creative is synced to, so a creative one routed seller rejected can no longer appear approved.
- Attaching creatives to an active media buy no longer leaves its per-package creative assignments stale (they were silently not updated once a buy went live), so get/list responses now reflect the attached creatives.
- A creative-only change to a routed buy no longer forces an unnecessary seller re-approval.
- Murph now returns a user-friendly “temporarily unavailable” message when the Anthropic API is overloaded (HTTP 529) or encounters a temporary server error (HTTP 500), instead of propagating an unhandled exception.
- Fixed a 500 error when executing or re-syncing a campaign whose draft media buy already exists and the campaign has optimization goals set. The goals are now stored correctly instead of failing with a database serialization error.
- Normalized creative format identifiers during seller sync when a product declares a base format that covers sized variants.
2.189.0 — June 23, 2026 at 2:18 PM UTC
- Creating products on an ad-server inventory source from chat now works reliably, and you can create several at once. Ask the agent to build a batch of products (for example from a spreadsheet) and approve the whole set in a single confirmation. Creation continues even if one product fails. You get a clear summary of which products were created and which failed, with the reason, so you can retry just the ones that didn’t land.
- You can now update several ad-server products at once from chat. Ask the agent to change a batch of products and approve the whole set in a single confirmation. Updates continue even if one fails. You get a clear summary of which products changed and which failed, with the reason, so you can retry just the ones that didn’t update.
- Fixed video creatives failing to upload to the ad server (“failed to upload creative”) when a video file was supplied for a VAST slot. The video was forwarded labeled as a VAST tag pointing at a raw MP4, which the ad server’s VAST parser rejected. The video is now correctly sent as a video asset on every upload path — including syncing creatives directly and creating a media buy — not only the format-adapted path.
2.188.0 — June 23, 2026 at 1:49 PM UTC
- Murph no longer writes the auto-vs-manual approval mode into the acceptance-policy document. The acceptance policy now covers content rules (which advertisers/creatives are accepted and what needs review); whether creatives and media buys auto-approve is the separate approval setting. This stops the acceptance-policy page from showing a stale “manual review” posture after the approval setting is changed.
- Fixed deleting a media buy leaving the ad-server order live. When a buyer deletes an executed media buy, the platform now cancels it at the sales agent / ad server first (archiving the upstream order, e.g. a GAM order) before archiving locally, instead of stranding an orphaned order.
- Fixed video media buys being rejected by the ad server. When a media buy was forwarded with a video creative, the video asset was sent without its name and pixel dimensions, so the sales agent rejected the buy. The forwarded video asset now carries its name, width, height, and (when available) duration.
- Storefronts can now be paid in more than one currency. A new
paymentCurrenciessetting lists the ISO-4217 currencies a storefront will be paid in (the primarydefaultCurrencyis always included). There is no FX — the currency a buyer pays in is exactly the currency the seller is paid in — so a storefront cannot sell a pricing option in a currency outside this set. Product discovery returns products in the buyer’s advertiser currency; if the storefront isn’t paid in that currency it returns no products (rather than ones the buyer could never buy). A media buy is accepted only when denominated in a single one of the storefront’s payment currencies. A storefront that sets nopaymentCurrencieskeeps its previous single-currency behavior, falling back to itsdefaultCurrency. - Murph now shows Approve / Cancel buttons in Slack when an action needs confirmation. Previously a Slack user had to reply with a long confirmation phrase to approve a gated change; now a tap approves it. Only the person who requested the change can approve it.
- Storefront readiness now surfaces the real per-track AAO compliance results (e.g. core, products, audiences) with their pass / fail / partial status and scenario tallies, instead of collapsing every agent to a single track that could report “0 tracks executed”.
2.187.0 — June 23, 2026 at 1:12 PM UTC
- Video media buys now carry the product’s exact required duration to the seller. When a product declares a canonical video format with a required duration, the package sent to the sales agent includes that duration (
duration_ms_exact/duration_ms_range) alongside the existing format selection, so duration-sensitive video inventory traffics correctly instead of dropping the requirement. - Product discovery now documents and types the accepted video delivery containers and codecs a seller will accept. For hosted-video formats,
formatOptions[].params.containers,params.video_codecs, andparams.audio_codecsadvertise the allowed values (for example, MP4 with H.264/AAC), so a buyer’s agent can avoid sending a creative that would be rejected downstream. VAST formats intentionally omit these — the codec is carried inside the VAST document. The legacyformatsreference array is also now documented on the product response. - Fixed approval queue action buttons so approving one media-buy approval does not show a busy state on unrelated approvals, and approval decisions now return immediately while source forwarding continues in the background.
2.186.0 — June 23, 2026 at 10:36 AM UTC
- Hosted video creatives now carry their duration. The duration is extracted from the video file (including non-faststart MP4s, via a tail read) when a creative is published and when it is adapted to a publisher format, so downstream duration limits — such as a sales agent’s maximum video length — can be checked. A missing duration is non-fatal: the creative still syncs, and only width/height remain required.
- Fixed a crash in the buyer catalogs view that prevented catalog details from rendering when an item count was shown.
- Fixed hosted video creatives failing to sync when they fill a VAST format slot. A hosted video used for a VAST slot is now sent as a video asset carrying its width and height, instead of being relabeled as a VAST tag pointing at the raw video file — which sales agents rejected as invalid (and which dropped the video’s dimensions).
2.185.0 — June 23, 2026 at 6:03 AM UTC
- Your business profile now reads as structured cards — the pitch buyers see, plus your channels, regions, verticals, and authorized domains as legible tagged groups — instead of a flat gray list, and “Update profile” is a clear primary action.
- Fixed approved creatives not delivering on approval-gated storefronts. When a seller approved a creative, it was created on the ad server but never associated with the line item, so it could not serve. The storefront approval now forwards the creative’s package assignment to the source, so the ad server creates the line-item creative association.
- Added a manual refresh control to the seller Approvals view, clarified pending media-buy review copy, and surfaced prior approval decisions with reviewer notes in the media-buy detail pane.
- Third-party storefronts can now leave Interchange merchandising tools off without being blocked by storefront-managed approval setup, and sellers can opt those tools back in from the Sales agent widget or Storefront settings.
2.184.3 — June 22, 2026 at 10:55 PM UTC
- Fixed an issue where
sync_creativescalls could fail withIDEMPOTENCY_CONFLICTwhen the set of package assignments changed between calls. The upstream idempotency key now includes a content fingerprint covering the creative and assignment payload, so different payloads always produce a distinct key even when the caller reuses its own base key.
2.184.2 — June 22, 2026 at 9:48 PM UTC
- Fixed a crash when updating a storefront’s publisher domain and operator domain in the same request.
2.184.1 — June 22, 2026 at 9:05 PM UTC
- Fixed creatives being synced to a seller without the media buy id or package assignments for media buys placed through a storefront. The storefront sync dispatch forwarded only the creatives and account, so the storefront fanned them out to every connected source unattached to a buy or package. The media buy id and per-package assignments are now forwarded through the dispatch, so creatives route to the buy’s source(s) and attach to their packages on the seller.
2.184.0 — June 22, 2026 at 8:11 PM UTC
- Signing up with an email domain that already has an account but no owner now lets the first verified user from that domain claim the account and become its owner. Previously, only brand-new domains could create an account: if an account already existed for the domain but had no owner, the first user was blocked and routed to request access (which no one could approve). Accounts that already have an owner are unaffected.
- Fixed creatives being synced to a seller without their package assignments for media buys placed through a storefront. The assignment step resolved formats from the wrong product record and produced no assignments, so creatives reached the seller unattached to any package. It now resolves each package’s own product formats and routed sales agent, so creatives are assigned to their packages on the seller for storefront-routed buys.
2.183.0 — June 22, 2026 at 8:02 PM UTC
- Fixed delivered spend (and other delivery metrics) being lost when a media buy is edited or re-synced. Delivery metrics are now carried forward to each new version of a media buy, and a one-time backfill restores metrics on existing media buys, so reported spend stays accurate after updates.
- Fixed client-side validation in the credentials form to allow Basic Auth with an empty password.
2.182.1 — June 22, 2026 at 6:16 PM UTC
- Fixed standalone creatives (submitted to a storefront without a media buy and held for manual operator review) failing to reach the underlying seller on approval. The forwarded sync_creatives request was missing an account, so it was rejected before delivery. The buyer’s account is now preserved on the review record and reused when the approved creative is forwarded.
2.182.0 — June 22, 2026 at 5:33 PM UTC
- Inventory sources that use basic auth or an API key can now be registered without supplying the secret up front. The source is created pending credentials, and the credential is collected afterwards through the secure in-chat form rather than being typed into the conversation. OAuth and no-auth sources are unchanged.
- Fixed two bugs in the storefront creative approval evaluator: the evaluator was incorrectly using the seller’s own brand ID as the expected brand when validating buyer-submitted creatives, and a brand metadata mismatch was treated as a hard block that prevented approval entirely. Brand mismatches now escalate to manual review instead of blocking.
- Fixed creative approval getting stuck in pending when ad-server forwarding fails. Operators can now approve a creative even when the source forward encounters a transient error — the approval decision is recorded immediately, and forwarding is retried separately.
- External sales-agent sources now accept Basic Auth credentials with an empty password.
- Murph now says “Scope3 has been notified” when it files a report and tells users they can track status under the ? menu. The offer to notify Scope3 also uses plain language (“Would you like me to notify the Scope3 team?”) so users know what the action means.
- Action buttons across the seller widgets now name what they do — “Fix this run”, “Build my profile”, “Update profile”, “Get a recommendation” — instead of naming the assistant (”… with Murph” / “Ask Murph”). The agent still does the work; the button just says the outcome.
2.181.0 — June 22, 2026 at 3:44 PM UTC
- Fixed a bug where hosted MP4 video creatives could not be forwarded to sales agents. Dimensions for MP4 video assets are now extracted from the file’s ISOBMFF container at upload and execution time, so video creatives proceed through media-buy execution without a “numeric width and height” validation error.
- Fixed service tokens showing no active agents when agents became active after the token was created. A token’s active agent list is now kept current whenever an agent is registered, activated, disabled, or reassigned, and existing tokens have been backfilled.
- Fixed an issue where creatives synced to a media buy placed through a storefront could fail to reach the underlying seller. The forwarded sync_creatives request was missing the account the media buy was created under, so it was rejected before delivery and the buy could stay in
pending_creatives. Creative syncs now reuse the correct per-source account. - Inventory-source health alerts are now owner-aware. When an official Scope3-hosted adapter (e.g. Pinterest, Reddit, Snap) has a runtime outage, Scope3 is alerted internally instead of notifying the seller about infrastructure they don’t operate. When the issue is the seller’s own adapter credentials, they still get a notification telling them to reconnect. Sources the seller operates directly are unchanged.
- Sellers now receive an “all clear” notification when a previously-unhealthy inventory source recovers, closing the loop on the unhealthy alert. It fires only for sources we actually alerted on, exactly once per outage, so it never spams.
- When a sales-agent connection check fails, diagnostics now report the specific failure — the HTTP status, whether it was an authentication/audience rejection, a timeout, or a network/DNS error, plus a redacted response excerpt — instead of a generic “not reachable” message. This makes it possible to tell an OAuth token or audience mismatch apart from an endpoint that is simply down.
2.180.0 — June 22, 2026 at 2:30 PM UTC
- Your acceptance policy now reads as a traffic-light — what you Accept (green) vs Decline (red) — instead of one flat gray list, so the two sides of the policy are clear at a glance. “Update policy” is now the clear primary action.
- Murph in-chat approval controls are more reliable. The window to approve a pending action is longer, so a review that takes more than a few minutes no longer lapses mid-decision, and a lapsed approval now shows an explicit “expired — ask again” state instead of a blank step that looked like the controls were missing. A pending approval also survives when the click that approves it is handled by a different server instance or after a restart, so approvals are no longer silently stranded. Approving an action started while signed in as another user (support-assisted setup) no longer fails with a confirmation error.
- Fixed several notification types that were silently failing to deliver — most notably the “your ad-server connection needs action” alert for sellers, plus outcomes-agent registration/update notices. These types were defined in the API but missing from the database’s notification-type list, so the platform dropped them instead of sending them; they now deliver as intended.
- Fixed a managed media buy failing at ad-server line-item creation when a product offered both a sized display format (e.g. 970×250) and the dimensionless display family format. The buy now forwards the sized format so the line item can be trafficked, instead of sending the dimensionless one alongside it and failing.
- Merchandising rules now has one clear primary “Update rules” action instead of a row of look-alike low-contrast buttons, and its actions are named for the task (“Update rules”, “Write merchandising rules”) rather than the tool.
2.179.0 — June 22, 2026 at 1:48 PM UTC
- You can now stop an in-flight Murph chat turn. While Murph is working, a Stop control appears in the composer — pressing it ends the turn immediately instead of waiting for it to finish. Stopping does not undo anything Murph already did on that turn (for example, a change it had already applied); the reply makes that clear.
- Storefront readiness now reflects when Stripe later disables, restricts, or disconnects your connected payout account. Previously, once payout onboarding completed it was recorded as done permanently — so if Stripe turned off payouts afterward, your storefront still showed billing as complete and “ready to sell” even though you couldn’t be paid out. Readiness now re-flags payout setup when Stripe reports the account can no longer pay out.
- Signal lifecycle status now shows a color-coded badge (active / draft / archived) instead of a flat gray pill where every state looked the same, reusing the shared seller-widget status badge.
- Fixed approved creatives getting stuck at “0/1 source” when forwarded to an ad server (e.g. Google Ad Manager) that reviews creatives asynchronously. An async-accepted creative is now correctly recorded as forwarded, so the operator’s approval lands instead of bouncing back as pending.
- Murph can now attach URL-backed creatives reliably. The
create_creative_manifestoperation now publishes its request schema throughdescribe_operation, so the agent uses the correct shape (a URL asset, an object-form format id) instead of guessing and failing. - Product discovery no longer hangs indefinitely when a single sales agent is slow to respond. Each agent now has a hard per-call ceiling, so one unresponsive seller is skipped (and reported) instead of stalling the whole discovery run.
- Stop Murph from re-issuing the same failing tool call turn after turn. When a request with byte-identical arguments has already failed in multiple previous turns, Murph now tells you the request keeps failing and stops retrying, instead of silently re-sending it. Mutations that are simply awaiting your approval are not affected.
- Fixed a confirmation-loop bug where Murph’s in-chat Approve button could misattribute a banner-attach (or other buyer write) approval to a discovery re-run when multiple pending confirmations were in context. The server-injected approval message now names the specific operation, so Murph cannot confuse which call to replay.
- Murph now presents the complete product discovery results to the user before offering curated recommendations. Previously, Murph could jump directly to a shortlist without giving the buyer a chance to browse the full inventory.
- Fixed the Murph sidebar recents empty state so it no longer creates unnecessary scrolling in compact layouts.
- Fixed Murph chat occasionally failing with a “network blip” error during long-running turns. The chat stream now sends a periodic keep-alive so a multi-minute response (for example a large product discovery) is no longer cut off by an idle-connection timeout.
- Fixed a loop where registering a third-party sales agent with no authentication kept redirecting to the credential form. Murph’s post-registration guidance (“add a bearer token later via /source credentials”) was being misclassified as an in-chat credential solicitation and replaced with a secure-credential redirect, leaving the registration visibly incomplete.
- Fixed the “Confirm currency” control in the seller setup checklist, which silently did nothing when clicked. The settlement-currency update is now applied, and a failed save surfaces an error instead of leaving the step unchanged.
- Storefront readiness now reflects real product availability for storefronts backed by a managed sales agent. Previously these storefronts always showed products as ready regardless of whether any products or signals existed; go-live now blocks only when a storefront genuinely has nothing to sell (no wholesale products and no signals to compose from). A storefront with signals but no pre-built products is correctly treated as sellable.
- The approvals view now shows a clear “you’re all caught up” confirmation when nothing is waiting on your review, instead of a bare line of text that could look like a broken panel. Introduces a shared empty-state used across seller widgets.
- Event source health now shows a color-coded status (Receiving / Needs attention / Not seen) that stays legible in dark mode, instead of a flat gray pill where every state looked the same. Introduces a shared status badge used across seller widgets.
- When a seller-operated inventory source stays unhealthy past a short threshold (default 10 minutes), Interchange now opens a Pylon support issue so the seller is reached in their support channel — and auto-closes it once the source recovers. Sporadic blips that self-heal within the threshold never open a ticket, and Scope3-hosted adapter outages route to Scope3 rather than the seller.
2.178.0 — June 22, 2026 at 8:54 AM UTC
- Sellers are now proactively notified when a third-party inventory source they operate goes unhealthy, so they can restore it before it stops serving demand — instead of only finding out by opening diagnostics. The alert is operational (always-on, customer-scoped) and debounced so a flapping source cannot spam. Official Scope3-hosted adapters are excluded for now; their owner-aware alerting is a follow-up.
2.177.0 — June 22, 2026 at 6:25 AM UTC
- Removing an inventory source no longer leaves it able to block your storefront. Source removal is a soft delete, so an unresolved trafficking error on a removed source previously kept readiness blocked indefinitely (and the resolved item lingered in your work queue). Readiness and the work queue now exclude items on removed sources.
- Inventory-source diagnostics now identify who owns a failure. The
diagnosisblock ofGET /api/v2/storefront/inventory-sources/{sourceId}/diagnosticsincludes anownerfield: for an official Scope3-hosted adapter (Pinterest, Reddit, Snap, …) a runtime failure is attributed to Scope3 — with guidance that it recovers automatically — instead of asking you to debug infrastructure you don’t operate. Adapter credential issues and your own external sales agents remain yours to fix.
2.176.0 — June 22, 2026 at 5:55 AM UTC
- A separate action-required indicator now appears in the top navigation when your storefront is blocked from selling, and opens the “Get ready to sell” readiness view so you can fix the blockers. It’s distinct from the notifications bell (which stays for passive updates) and only shows while there’s something to act on, clearing once your storefront is ready.
- Ad-server connection alerts (“sync action required”) are now always-on like other storefront readiness alerts — delivered to your whole team and shown in the notifications feed regardless of preferences, since a broken ad-server connection stops your storefront from selling. They no longer appear as a toggle in notification settings.
- Storefront readiness alerts — your storefront was paused, or products aren’t ready to traffic — are now delivered to your whole team automatically rather than being something you had to opt into. These operational alerts can’t be muted, so a storefront problem never goes unnoticed, and they no longer appear as toggles in notification settings.
- Fixed the Ad server item in the seller navigation doing nothing when clicked — it now opens your ad-server inventory view (connections, sync status, wholesale products, and signals), the same surface the inventory link already opened.
- Notification settings no longer show a duplicate “Storefront” category, and the list now only includes the categories relevant to your account — buyers see buyer notifications, sellers see storefront notifications. The sales-agent notification category is now labeled “Sales agent.”
- Murph now acts immediately when you approve a change it proposed (for example a campaign start-date edit), instead of repeating the confirmation in a way that left it unclear whether Murph had already made the change or was still waiting on you.
- Fixed Murph confirmation messages to unambiguously use future tense so users can tell whether Murph has acted or is waiting for their approval.
- Murph confirmation and approval summaries now use plain language — no API field names, ISO codes, JSON paths, or internal schema reasoning. Before any gated action (campaign creation, policy write, advertiser setup), Murph describes what will happen in terms of the buyer’s intent, not the underlying API call structure.
- Murph no longer warns that a campaign or flight start date of today is in the past — a start date of today is valid and is accepted without friction. When you ask which inventory covers a channel or region, Murph now leads with the storefronts that match and offers to run discovery for actual products and pricing.
- Fixed duplicate approval prompts appearing for product discovery actions in sessions where discovery had previously been run. Returning buyers no longer see a second confirmation gate when re-running discovery in the same conversation.
- Improved the error message shown when Murph is temporarily unreachable server-side. The message no longer instructs users to check their own connection when the issue is on Scope3’s end.
- Murph no longer infers an advertiser’s primary currency from seller-side storefront data (name, domain, region, pricing, or rate card). Currency is now always sourced from the buyer’s own stated preference or by asking directly.
- Fixed an issue where Murph incorrectly rejected today’s date as a campaign flight start date. The validator now correctly uses UTC midnight for date comparisons, matching how ISO 8601 date strings from clients are parsed.
- A new seller’s menu now keeps the focus on getting set up. Until the storefront
- is live, the Merchandise and Operate sections start collapsed — one click opens
- them — so the rail shows the foundational steps instead of every option at once.
- They expand automatically once the storefront is live, or whenever you’re working
- in one of them.
- The Approvals item in the seller navigation now opens the full approvals view, where you can see every pending creative review and media-buy approval and approve or reject each one inline — instead of a read-only summary of the most recent few.
- The Self-serve buyers item in the seller navigation now opens its full in-chat view, where you can create and share your buyer invite link, copy or disable it, and approve, decline, suspend, or reactivate the buyers who have joined — all in one place.
- The Business profile and Pricing & terms items in the seller navigation now open their full in-chat views — your profile, voice, and pitch; and your rate-card rules and approval settings — instead of a condensed summary panel.
- Once a seller’s storefront is live, the menu now collapses the set-once “Set up”
- section and leads with the ongoing Merchandise and Operate work — mirroring how a
- not-yet-live storefront keeps Set up open and collapses the rest. Collapsed
- sections are one click away, and any section you’re working in stays open.
- Rebuilt the seller “Get ready to sell” surface into a go-live readiness dashboard and extended it to reflect live operational health. It now leads with your go-live progress and one clear next action, lets you confirm simple settings like your settlement currency right in the surface, and offers accept-default / upload-your-own / build-with-help for your acceptance policy. Once you’re live it stays a glanceable health check: if an inventory source goes down or buys fail to traffic, it flags exactly what’s stopping you from selling — with direct “reconnect” and “resolve” actions — in step with the action-required indicator.
- The Test runs item in the seller navigation now opens its full in-chat view: your sandbox test history, and for each run the per-sales-agent breakdown (which agents returned products, came back empty, or failed — with the raw call payload), the run’s context, and a one-click handoff to Murph to fix a failed run.
- When a campaign’s selected products include a sales agent that can’t be used with the campaign’s routing type (for example, a decisioned storefront selected into a routed campaign), that agent is now skipped with a warning instead of failing media-buy creation for the entire campaign. Compatible sales agents in the same campaign still get their media buys.
2.175.0 — June 22, 2026 at 1:06 AM UTC
- Advertisers are now unique within a customer by the pair of brand domain and primary currency, instead of by brand domain alone. The same brand domain can back more than one advertiser as long as each uses a different currency (e.g. one in USD and one in EUR). Creating — or updating an advertiser onto — a brand domain + currency pair already taken by a sibling advertiser returns a conflict.
- Murph now coaches sellers all the way through acceptance-policy setup instead of stopping to say the decision “has to come from the operator.” When a step asks which advertisers or creatives to accept, decline, or send for review, Murph asks the questions, drafts the policy, and writes it on your confirmation — rather than handing back a generic template. The in-product recovery after a hiccup also no longer implies a change that already saved cleanly failed.
- Fixed Murph chat scrolling and added clearer debug-call provenance, including timestamps, initiators, and whether calls came from sandbox tests or non-test demand traffic.
- Murph now proactively coaches sellers whose storefront isn’t live yet. On the
- first message of a conversation, Murph leads with where the storefront stands —
- how many steps remain before it can answer its first buyer brief and what the
- immediate next step is — and offers to walk through it one step at a time,
- instead of waiting to be asked. The offer is made once per person, with a
- lighter “pick up where you left off” nudge on a later visit, and it stops
- automatically once the storefront goes live.
- When a seller opens Murph without an active conversation, it now opens directly
- to the right place — the setup checklist while the storefront isn’t live yet,
- the dashboard once it is — instead of a blank screen next to the full menu.
- Starting a new chat still gives a clean chat to type into.
- Sellers can now attach pricing to wholesale signals (CPM or revenue-share), so audience signals can be sold with an incremental price.
2.174.0 — June 21, 2026 at 3:47 PM UTC
- Storefronts now flag products synced from a connected sales agent that can’t be trafficked — for example, video formats missing a duration. The issue appears in your storefront health and raises a notification naming how many products are affected, so you can fix them in your sales agent and re-sync. This extends the same not-traffickable detection that managed ad-server products already have.
- Fixed Murph chat consistently failing with “Murph chat stream ended without a result” even though the reply was generated and saved. The streaming response now reliably delivers its final result.
- Product activity entries now record the full set of seller-meaningful fields (delivery type, inventory type, formats, pricing, exclusivity) instead of only name and pricing, so edits to those fields are no longer silently omitted from the activity feed. The audit row no longer stores the raw product payload, keeping unbounded upstream data out of the activity log.
- Murph no longer stops a conversation when an account reaches its daily usage
- budget. During the beta we meter usage and watch instead of blocking, so a
- seller or buyer is never cut off mid-task. A high runaway-safety limit still
- guards against abuse or a stuck loop.
- The seller rail’s “Get ready to sell” now opens the coached go-live checklist (the Setup widget with a highlighted “do this next” step and a walk-me-through option) instead of the older state drawer — so the most important setup row lands a new seller on the guided surface.
- The “connect an inventory source” and “ad-server source” go-live checks now name the actual ad servers (Google Ad Manager, FreeWheel, SpringServe) and the sales-agent option in their guidance. This makes the step clearer for a new seller and routes Murph’s “walk me through it” hand-off to the GAM-access documentation, so the most common setup question is answered at the moment of friction.
- Reorganize the seller agent’s navigation rail into three teaching sections — Set up, Merchandise, and Operate — with plain-language labels, so a new publisher can see the whole journey at a glance. Renames the opaque rows (“Demand inbox” → “Demand”, “Selling terms” → “Pricing & terms”, “Source sales agent” → “Sales agent”, “Source ad server”/“Inventory” → “Ad server”, “Go live” → “Get ready to sell”, and more), splits ad-server vs. sales-agent connection into distinct rows, and surfaces Acceptance policy, Merchandising rules, and a Components coaching entry directly in the rail.
- Added a Setup view to the seller chat experience. Ask Murph “is my storefront set up?” (or use
/setup) to see your go-live checklist — the single most important next step is highlighted, required steps come first, and every step can be done with Murph right there. “Walk me through it” hands the whole sequence to your agent. - Renamed the app support menu status link to “Scope3 service status”.
- The not-traffickable product check now covers every connected source’s synced catalog — not just third-party sales agents — and runs even when a storefront also has a managed ad server, so any source with products that can’t be trafficked (e.g. video missing a duration) is caught and named per source. Managed ad-server sources continue to be covered by their own setup checklist.
2.173.0 — June 21, 2026 at 4:58 AM UTC
- Creative changes now appear in your activity feed: creating, updating, archiving, and assigning or removing a creative to/from a campaign — and bulk creative updates — are each recorded with who did it and when. Previously the creative service wrote no activity at all.
- More seller actions now appear in your activity feed: creating a storefront, resetting brand verification, linking an agent as an inventory source, and approving or rejecting an ad-server (ESA) workflow are each recorded with who did it and when. This clears the last of the known audit-coverage gaps.
- Your activity log is now reachable from chat: type
/activityin the composer to open it. The log opens on recent account-wide activity instead of requiring you to pick an advertiser and campaign first — those filters now refine the view rather than gate it. The buyer Diagnostics shortcut also now opens the diagnostics view as intended. - Storefront API calls scoped to your own storefront (listing products, demand signals, the dashboard summary, and responding to a demand signal) no longer require you to pass a
storefrontId— the server resolves your storefront from your account. A wrong or guessed id is corrected automatically, and calling before you have a storefront returns a clear “start onboarding first” message instead of a confusing missing-parameter error. Inventory-sourceexecutionTypeandstatusvalues are documented as the uppercase enums the API requires (AGENT,PENDING/ACTIVE/DISABLED). - Added a Dashboard view to the seller chat experience. Ask Murph “how am I doing?” (or use
/dashboard) to open your storefront performance at a glance — win rate, booked budget, delivery, how your agent’s negotiation postures convert, and what to improve — without leaving chat. - Storefronts now flag go-live blockers when a product cannot be trafficked (for example, a video product missing its duration). The blocker is surfaced the moment you ask your storefront agent about capabilities, and it raises a notification (with email for opted-in operators) — naming how many and which products are affected — so you know your storefront is not live and exactly what to fix.
2.172.0 — June 20, 2026 at 3:21 PM UTC
- Added an in-chat Acceptance Policy view to the seller Murph experience — see your storefront’s acceptance policy (which advertisers, categories, and creatives your agent accepts or declines) with version history, and ask Murph to summarize, explain, or update it.
- Added an in-chat Activity Log for storefronts. Ask your agent to “show the activity log” (or type
/activity) to open a read-only feed of recent changes — each entry shows what changed, whether it was a person, the agent, or automation, and whether the action succeeded, was denied, or was blocked. You can also just ask “who changed this?”, “what changed yesterday?”, or “what got blocked?” and get the answer in chat. - Added an Approvals view to the seller chat experience. Ask Murph for “Approvals” (or use
/approvals) to see your review-gate settings alongside anything waiting on you — pending creative reviews and pending media-buy approvals — and hand decisions or gate changes back to Murph in chat. - Activity feed entries now record how each action was initiated. A new
actorOriginfield on buyer and storefront audit logs distinguishes a change made directly by a person (human) from one the Murph agent made on a user’s behalf (agent), as well asautonomousandsystemactions. The activity timeline shows a “via Murph” badge on agent-initiated changes so you can tell at a glance who — or what — made a change. - Added an in-chat Business Profile view to the seller Murph experience — see your storefront’s channels, regions, verticals, properties, and the pitch buyers see, and ask Murph to update it.
- Added an in-chat Merchandising Rules view to the seller Murph experience — see how your agent turns your inventory into sellable products (your operating instructions), with version history, and ask Murph to summarize or update them.
- Sellers now choose the country their business is based in when connecting a Stripe payout account. This country is set when the account is created and determines the payout/settlement currency (for example, a seller in Germany settles in EUR), so it can no longer default to US. Provisioning a Stripe Connect account now requires a
country(ISO 3166-1 alpha-2) value, restricted to countries Stripe supports for payouts; an unsupported country returns a clear validation error instead of a generic failure. - The seller Approvals view is now a place to do the work. Open Approvals (or
/approvals) to drill into a pending creative review or media-buy approval, see how it was pre-screened (the policy/brand/readiness verdict and what was flagged), preview hosted creatives inline, and approve or reject it with a note — without leaving the view. Changes to live media buys are flagged; approving a flagged item asks for a deliberate confirm; and when an approval can’t reach your ad server you now get the specific reason (and the item stays pending to retry) instead of a generic error. Approval automation settings now live with your other policies rather than in the queue. - Advertiser edits, archives, and restores — and attaching a discovery run to a campaign — now appear in your activity feed, with who made the change and when. Previously only advertiser and campaign creation was recorded.
- Closed two gaps where changes weren’t reaching the activity log. Creating an advertiser is now recorded (it previously left no audit entry, so “who created this advertiser?” had no answer), and a new
ADVERTISERresource type is filterable in the activity feed. Storefront product changes — including floor-price edits — are now recorded as updates with a before/after diff instead of being logged as a fresh “create” with no history; identical re-saves are no longer logged at all, so routine discovery refreshes don’t add noise. - Managed ad-server source changes and billing changes now appear in the activity log. Connecting, reconfiguring, rotating credentials for, deactivating, and reactivating a managed ad-server source, plus connecting a payout account and updating billing terms, are each recorded — so operators can see who changed what. Credentials and Stripe identifiers (account ids, onboarding links, client secrets, tokens) are never written to the log.
- Product discovery now only surfaces products priced in the storefront’s settlement currency. A storefront sells in one currency and can’t settle a buy in another, so products (Chef-composed or passed through from sources) with no pricing option in the storefront’s currency are no longer returned, and off-currency pricing options are dropped from the products that remain. Storefronts that have not yet confirmed a settlement currency are unaffected.
- The buyer and storefront activity feeds can now be filtered by who and how. New query parameters on the audit-log endpoints let you narrow to a specific actor (
actorUserId/actorUserEmail), to how a change was initiated (actorOrigin, e.g. only changes the Murph agent made), to a single resource (resourceId), and to specific actions (actions). This makes questions like “what did the agent change last week?”, “who deleted this?”, and “what has this user done?” answerable directly. Murph’s recent-activity lookup also now reports the origin and the before/after of each change, supports an end-of-window bound, and returns more rows. - Setting credentials now opens the sales-agent management surface (where credentials live alongside setup and diagnostics) instead of a separate standalone credentials screen that showed “no sources found”. The seller rail’s sales-agent entry opens the same consolidated widget.
- Connecting an ad server no longer shows a server error on the Signals or Creative-formats tabs when the upstream ad-server adapter is briefly unavailable or doesn’t advertise those capabilities. Capability and creative-format probes now degrade gracefully to an “unavailable / not supported yet” state instead of failing the whole source view, so inventory, signals, and formats stay usable independently.
- Simplified seller source-management entry points around Source ad server and Source sales agent, with credentials, setup checks, and diagnostics managed in the sales-agent source widget.
- Media buy responses now populate creative formats for composed (storefront-curated) products, which previously came back empty because composed products aren’t in the raw product cache. The media buy list additionally fills in the product name and publisher for composed products. These are resolved from the storefront’s composition data and product index.
- Fixed media buy execution against embedded storefront sales agents whose in-process ADCP endpoints are stored as relative paths.
- Clarified that a storefront settles in one currency, which must match its connected Stripe payout account. The go-live currency copy no longer implies the currency is derived from your ad server, and the storefront agent now explains that clearing a second currency means setting up a second storefront rather than adding a currency to an existing one.
- The activity log now records mutation attempts that did not take effect, not just successful changes. Actions blocked by a permission or Terms-of-Service gate are recorded as “denied” and ones that errored mid-execution as “failed”, so you can answer “who tried to change this and why didn’t it stick” — including the “I didn’t do that” dispute case. The buyer and storefront audit-log endpoints accept a new
outcomefilter; by default the feed still shows only changes that succeeded, and passingoutcome=denied(orfailed) surfaces the attempts across all resource types. Murph’s recent-activity lookup can report and filter on the outcome too. - Sellers can now ask Murph about their storefront’s activity log — who changed the storefront config, billing, or a managed ad-server source (connect, reconfigure, rotate credentials, deactivate), whether it was a person or the agent, and what got blocked or failed — over a time window. Connecting a Stripe payout account now appears in the seller activity feed.
- Advertisers are now single-currency.
primaryCurrencyis required when creating an advertiser, and it can only be changed while the advertiser has no campaigns — once the first campaign is created the currency is locked. Every campaign is created in its advertiser’s currency: ifbudget.currencyis supplied on campaign creation it must match the advertiser’s currency, otherwise the advertiser’s currency is used. - Source management is clearer and more self-serve in Murph and the seller widgets:
- Murph now explains the difference between an ad server source and a sales agent source and which you need, instead of dead-ending on the question.
- “Debug my sales agent” no longer silently assumes your ad server — when you have both, Murph asks which one, then diagnoses the right source (live connection probe, ranked likely causes, and next steps for an external agent; sync health for an ad server).
- The ad-server source widget adds a Health view that lists every blocking and warning issue with the exact next action — including a one-click Set default advertiser fix for the most common go-live blocker — and now consistently calls it your “ad server” (not “ESA”).
- The sales-agent source widget can now connect a new external AdCP agent directly (name, endpoint, protocol, credentials) instead of leaving you with nowhere to start.
- Opening a source widget now previews what you can do next instead of a bare “Opening…”.
- Ensured approved storefront creatives forwarded to third-party inventory sources register callback webhooks when asynchronous source-side review is available.
- Storefront media buys are now validated against the storefront’s settlement currency. A
create_media_buywhose stated budget currency differs from the storefront’s confirmed currency is rejected with anINVALID_REQUEST(currency_mismatch) error rather than silently accepted. A storefront clears in one currency — to transact in another currency, use a storefront that clears in it. Buys that omit a currency are unaffected and are treated as denominated in the storefront’s currency. - A storefront’s confirmed settlement currency is now verified against its connected Stripe payout account before go-live. The payout account’s settlement currency is captured when Stripe onboarding completes, and go-live is blocked if the storefront’s currency doesn’t match it — preventing payouts that would otherwise silently convert into a different currency.
- Campaign creation now accepts a
feeTypeofGROSSorNET(defaults toGROSS), and campaign pricing is resolved through the Pricing Engine.GROSSmeans the budget is the all-in total the customer pays and the Scope3 fee is carved out of it (media budget = budget − fee);NETmeans the budget is the media spend and the fee is added on top (media budget = budget; total paid = budget + fee). The fee is the same percentage of the budget either way, and the campaign’s total budget is stored unchanged.feeTypeis returned on the campaign and is immutable after creation. The pricing rate is pinned at creation and refreshed on each budget edit while the campaign is still a draft; once the campaign is live the rate is frozen and budget edits re-split at that pinned rate — so a rate-card change can never silently re-price a running campaign. Media buys always draw against the media budget, never the total budget. Media-buy and package budget updates are now validated against the campaign’s media budget — raising a media-buy budget past what the campaign can fund is rejected instead of silently over-allocating.
2.171.0 — June 19, 2026 at 1:58 PM UTC
- Improved campaign media-buy status responses to distinguish draft, pending creative review, upstream submission, and delivery states, and added read-only ESA media-buy diagnostics for verifying upstream persisted buy state.
- Allow Murph creative workflows to attach MP4 video files up to 50 MB and preserve creative dashboard deep links from account-level URLs.
- Added in-chat Test Runs and Selling Terms views to the seller Murph experience, restored direct Murph seller navigation, and opened inventory sources in the inventory setup widget.
2.170.0 — June 19, 2026 at 11:41 AM UTC
- Advertise AdCP 3.1 release negotiation on storefront agents and use the stable 3.1 client pin for external seller calls.
- Storefront get_products now honors pricing currency filters when returning pass-through source products.
- Added customer notifications for managed storefront sync issues that require reconnecting an ad server adapter.
- Added embedded sales agent webhook and buyer discovery cache diagnostics to ESA status and admin sync health, with clearer storefront product-authoring validation in Murph.
- Storefront media buy creation now echoes source-returned package status fields while preserving storefront product and package identifiers.
- Improved chat widgets so they use the available width by default and long Inventory Sources sync views remain scrollable.
- Storefront product discovery now preserves product-scoped signal targeting metadata returned by upstream sources.
- Storefront product discovery now preserves vendor metric reporting and optimization metadata returned by upstream sources.
2.169.0 — June 18, 2026 at 8:39 PM UTC
- Publisher discovery now follows redirects and the ads.txt
managerdomainfallback when resolvingadagents.json, so domains managed by a network (e.g. Raptive/CafeMedia) correctly surface their authorized agents and properties. - Murph can now set authentication credentials on an ADCP inventory source directly in chat through a secure credential form — basic auth and API key are entered inline, and OAuth sources get an Authorize button that opens the provider’s consent page. This replaces a storefront menu path that no longer existed. Open it with the
/source credentialscommand or by telling Murph you have credentials to provide. - Fixed a crash on
POST /api/v2/storefront/resolve-brandwhen a brand manifest from the AAO registry contained non-string field values (arrays, numbers). The advertiser-industry classifier now filters these out instead of throwing a TypeError.
2.168.0 — June 18, 2026 at 7:16 PM UTC
- Fixed creative format validation incorrectly rejecting raw video creatives for VAST video placements when the publisher’s format declared the video slot without an explicit asset type. These creatives can now be assigned to and kept on media buys for those placements.
2.167.0 — June 18, 2026 at 6:04 PM UTC
- Fixed Murph approval controls so pending storefront setup confirmations stay visible when a conversation is reopened and stale approvals no longer block follow-up setup.
- Fixed Murph wrongly interrupting unrelated actions (like filing a report) with an ad-server credential redirect, and pointed the secure credential link for FreeWheel and SpringServe setup at the working inventory-source screen.
- Storefront legacy links now open the matching Murph storefront surfaces.
- Route the buyer creative workspace root through Murph so all creative asset entry points share the dashboard surface.
- Seller inventory-source links now open the shared Murph diagnostics widget instead of a standalone legacy page.
- Legacy advertiser and supply discovery URLs now open the equivalent Murph buyer surfaces.
2.166.0 — June 18, 2026 at 3:51 PM UTC
- Added a source diagnostics MCP app for third-party sales agents and modular inventory sources, including tool-level latency, timeout, outcome, and next-step rollups that Murph and other MCP hosts can launch with “open diagnostics.”
- Fixed an error when approving an action in Murph (such as filing a report). Approvals
- now reliably go through instead of occasionally failing with a confirmation error.
- Route the buyer activity deep link through Murph while preserving the full campaign activity workflow.
- Route advertiser-scoped creative asset deep links through the Murph creative dashboard surface.
- Migrated legacy product URLs with equivalent Murph surfaces so planning briefs, reporting, supply browse, and buyer connections open inside the unified Murph surface instead of standalone pages.
- Added a
+menu and/commands to the Murph composer so launchable MCP widgets open from chat instead of static navigation. Sellers can open demand inbox, buyers, and sales-agent diagnostics from the composer, including/diagnosticsand/inventory sources.
2.165.0 — June 18, 2026 at 1:18 PM UTC
add_discovery_productsandapply_proposalnow report whether the discovery session is attached to a campaign. The response includescampaignBound, and when it isfalseacampaignWarningexplains why no campaign reflects the products: either the session was never attached to a campaign (passcampaignId, or run discovery withcampaignId, to bind it), or the campaign it was attached to has been archived (restore it, or passcampaignIdfor an active campaign). This removes the “add reported success but the campaign still shows 0 products” confusion.- Improved media buy creative validation errors so invalid video assets are reported as invalid requests instead of source availability failures.
2.164.0 — June 18, 2026 at 10:13 AM UTC
- Added an explicit Linear visibility status to Murph escalation artifacts so clients can distinguish unavailable Linear tickets from role-redacted ticket references.
- Added customer-facing guidance for connecting ad platform accounts, including recommended Meta, TikTok, Google Ads, and other platform access levels, and linked it from the Connections setup experience.
- Improved activity diffs so long brief-style updates remain readable.
- Buyers can now request
audioanddoohchannels indiscover_products. Both were previously rejected by schema validation even though the underlying ADCP layer already supported them. - When
discover_productsreturns zero results, the response now includes a specific reason - e.g. how many publishers were queried, how many were skipped and why, or whether no publisher connections are configured for the account. This prevents agents from blind-retrying identical calls. - Keep MCP connections alive during long-running tool calls. Tool calls that take several minutes to complete (such as product discovery against a slow sales agent) no longer get dropped by the connection idle timeout before the result is returned.
- Fixed Murph incorrectly redirecting to the secure credential form when explaining ad-server setup steps. Guidance like “you’ll need to provide your FreeWheel credentials to complete the setup” is no longer mistaken for an in-chat credential request, while Murph still redirects genuine attempts to paste passwords or tokens directly in Slack.
- Fixed DMA code-to-market-name resolution so the buyer agent correctly identifies Nielsen DMA markets by name rather than relying on model memory.
- Fixed a bug where a campaign with a stranded DRAFT media buy (from a prior failed execution) could not be re-executed. The execute endpoint now bypasses the discovery session gate when DRAFT buys already exist, and the media-buy-status endpoint now surfaces DRAFT buys so they are visible rather than silently hidden.
- Fixed Murph starter prompt labels so they use the selected interface language instead of falling back to English.
- Ask Murph can now show you a “Your requests” panel — the issues and requests you’ve escalated to the Scope3 team, each with its current status, how long ago it was filed, and what’s happening next. Ask Murph to show your requests (or use the escalations shortcut) and the panel renders right in the chat, covering everything from open to resolved.
- Fixed product discovery only returning the first page of a sales agent’s catalog. Both catalog enumeration and buyer product discovery now retrieve the full catalog by following
get_productspagination, so products on later pages (for example CTV, interstitial, or banner inventory listed after a first page of other formats) are discoverable and available for deals. Large catalogs that previously truncated at the first page are now returned in full. - Make a curator’s media buy from a pool seller work end to end. Two gaps blocked the in-process buy that only a real (un-stubbed) buy exercised: the bridge’s SDK client refused
create_media_buybecause a storefront advertises itself as a discovery agent (its capabilities null out themedia_buyprotocol), and the curator’s forward only accepted acompletedupstream status and rejected thepending_start(accepted-but-trafficking) state a storefront seller returns. The bridge now skips the pre-flight feature gate for the trusted in-process seller, and the forward accepts a linked seller’s create whenever it returns a media buy id. Adds an end-to-end real-Postgres test of the full cascade (curator → bridge → seller → modular terminal) with both spread-ledger legs booked.
2.163.0 — June 17, 2026 at 11:57 PM UTC
- Added selection and refinement actions to buyer starter proposal cards, and surfaced seller-side demand coverage in storefront readiness.
- Added seller documentation for diagnosing third-party sales-agent inventory sources, including source health, recent AdCP activity, and buyer discovery debug output.
- Brand resolution now classifies each resolved brand into a canonical AdCP advertiser-industry code (e.g. a steakhouse →
food_beverage.restaurants), surfaced asadvertiserIndustryon the brand manifest. Brands now share one category vocabulary across the platform and with AdCP, so a brand.json can advertise its canonical industry. This is the foundation for category-based starter briefs. - Standardized the buyer dashboard page headers. Every section — Campaigns, Creatives, Data sources, Reporting, and Activity — now renders a consistent header at the correct size, with each section’s controls in the header: Reporting’s date filters, Creatives’ campaign filter, Data sources’ Catalogs/Conversions tabs, and Activity’s kind filter. Buyer page headers also stay pinned while scrolling, and the Planning Briefs page uses the standard page-header layout for a consistent title, description, and primary action.
- Storefront interchange is now an open marketplace pool. A curator storefront automatically discovers and composes wholesale inventory from every listed storefront whose offerings match the curator’s own channels — there is no per-storefront linking or approval step. A storefront participates simply by being listed in the marketplace, and a seller’s price floor and content policies are always enforced on every resale.
- Streamlined the storefront navigation. The rail is reordered around going live and daily demand, renamed for clarity (“Reporting”, “Agent training”), and Team and Billing moved into Settings to keep the rail focused on selling. Storefront testing now lives in the Demand inbox.
- Fixed a bug where multiple Anthropic API 500 errors from the same call site would each open a new GitHub issue instead of deduplicating onto a single issue. The Anthropic SDK embeds a unique
request_idin each error message, which was causing the error fingerprinter to generate a distinct hash per occurrence. - Fixed the activity feed rendering a campaign brief change one word per line. Long brief edits now show the new brief as a full-width paragraph instead of a cramped side-by-side diff.
- Customer account lists now include active child accounts accessible through parent administrator permissions.
- Fixed publisher authorization discovery so live authorization can clear stale verification results, and Murph checks specific seller domains with a fresh domain lookup instead of browsing cached catalogs.
- Corrected storefront setup documentation to use the canonical Interchange storefront agent URL and updated managed ESA publisher-property lookup to avoid treating ESA authorization checks as the source of truth.
- Fixed
PUT /storefrontrejecting a settlement-currency update with “At least one field must be provided to update”.defaultCurrency(andsupportedLanguages) were valid fields but were missing from the update body’s non-empty check, so sending onlydefaultCurrency— the call required to clear thecurrency_confirmedgo-live blocker — failed validation. These fields now satisfy the check, so a currency-only update works. Also documented the field in the storefront agent skill’s Update Storefront reference. - Fixed media buy status not updating for buys placed through a storefront. A storefront fans a single media buy out to multiple upstream sources, so its status is now rolled up from those per-source statuses rather than left stuck at “pending approval”. A buy that is live upstream now correctly reports as active, and reflects paused, rejected, completed, and other states the same way.
- Localized buyer activity filters, empty states, pagination copy, and invitation accept prompts.
- Localized advertiser management copy, table labels, advertiser dialogs, and archive/restore prompts.
- Localized buyer storefront connection copy, status labels, account prompts, feature controls, and notification preference labels.
- Localized Discover Supply table, page, note, and submit copy.
- Localized storefront account card metadata and archive dialog fallback copy.
- Localized storefront card preview fallback messages and Supply page empty states.
- Localized storefront card channel/status labels and Supply page filter copy.
- Localized storefront demand signal cards and locale-formatted their budget, flight, and fit details.
- Localized storefront drawer readiness, pricing, and performance summaries.
- Localized storefront drawer chat prompts for setup, readiness, approvals, catalog, and document-processing actions.
- Localized storefront test-run diagnostics and helper status labels.
- Localized storefront inventory and source status labels across source tiles, details, and catalog rows.
- Localized storefront inventory-source chooser, filters, empty states, and adapter connection labels.
- Localized storefront link request dialogs and inbound request actions.
- Localized storefront setup task controls and demand contact editing copy.
- Localized storefront setup task rows and translated their status, action, and sync-health copy.
- Localized the storefront state drawer, including setup guidance, source diagnostics, buyer invite actions, and document-processing details.
- Re-validating a publisher’s
adagents.jsonis now reliable when a fix has just gone live. If you publish or correct youradagents.jsonand product creation is still rejected as “not authorized”, you can ask the assistant to re-check your domain and it will re-read the live file, refresh authorization, and re-sync your properties so you can create products without an out-of-band support request. Storefront agent discovery also now self-heals a stale authorization flag when your liveadagents.jsonis valid, regardless of how many properties are already registered. - Murph campaign summaries now include stored campaign constraints, including AdCP geo metro targeting codes.
- Storefront interchange discovery now scopes the ambient wholesale pool by geo/region in addition to channel. A curator storefront discovers wholesale inventory from LISTED storefronts whose declared regions overlap its own (legacy region-code aliases are honored). Region scoping is lenient on the seller side: a storefront that has not declared regions stays discoverable everywhere — only a seller that explicitly serves non-overlapping regions is filtered out.
- Restored seller demand inbox and buyer management surfaces as MCP app widgets in the Murph chat shell.
- Brought the storefront chat experience in line with the buyer one: New chat and recent conversations are always visible in the rail, prompt suggestions now fill the composer (so you can add context before sending) instead of sending immediately, the chat input shows only in the chat view, and rail spacing, labels, and suggestion styling are tightened and consistent across buyer and seller.
- You can now delete a chat from Murph’s Recents list: hover a conversation, open the ”⋯” menu, and choose Delete chat. Deleting removes the chat from your sidebar right away. Behind the scenes the conversation is retained so support can review product issues, but it no longer appears anywhere in your view.
- The storefront overview now shows your realized margin and margin % alongside delivery metrics, so a curator can see resale profitability at a glance — what you charged buyers, minus what you paid sources — for the current period. Margin is reported in your primary settlement currency; it fills in once your media buys start delivering.
- The buyer assistant can now look up an operation’s exact request schema and a canonical example before calling it, so it gets field names and types right the first time instead of guessing. It also adds discovery products to a campaign through a verified workflow that confirms the campaign-facing product count actually rose — preventing a silent zero-count attach from being reported as success.
2.162.0 — June 16, 2026 at 6:58 PM UTC
- Fixed a media buy failing to save at execution when an inventory source returns tokenized product identifiers containing colons (e.g.
wh:<source>:<product>). The id validation now accepts the colon-delimited token format these sources use, so the buy completes instead of erroring with an “invalid format” message after the source already accepted it.
2.161.0 — June 16, 2026 at 5:20 PM UTC
- Added
GET /api/v2/storefront/reporting/margin— a curator’s resale P&L. It reports booked vs realized buy/sell/spread and margin %, rolled up buyer → media buy → package → source leg, so a storefront operator can see what it paid each source, what it charged its buyer, and the spread between them. Amounts are signed (a resale at a loss is shown, not hidden) and are reported per settlement currency, never summed across currencies. This is a cumulative as-of snapshot, scoped to the calling storefront. - When you create an advertiser from a domain, the brand profile shown for confirmation is now the exact profile that gets saved — a freshly built profile is briefly cached and reused at save time instead of being re-derived, so what you confirm is what you get.
- Brand resolution now builds a profile from a buyer’s own website when the brand isn’t in the registry. Previously a domain that wasn’t registered (most local, regional, and smaller brands) resolved to nothing; now we read the site’s declared metadata (name, logo, description), its page content, and — when a brand publishes one — its
/llms.txtsummary to fill in name, industry/vertical, tagline, audience, and tone, so the buyer still gets a co-branded experience and a personalized proposal. Harder-to-read or ambiguous sites are read more thoroughly, including additional pages. The profile is always shown for confirmation and is never saved until the buyer reviews it. - When creating an advertiser, a buyer can now look up their brand by domain and see a “here’s how I see you” confirmation card — logo, name, and industry/tagline resolved from the brand registry — before committing. A new
POST /api/v2/buyer/brands/resolveendpoint resolves a domain to a brand-confirmation card with no side effects; the buyer confirms by creating the advertiser as before. Unregistered domains return a friendly “we’ll create one when you save” state instead of an error. - Added a clear way to return from account settings to the main account screen.
- Restructured the Murph seller storefront surface so Dashboard and setup action areas are first-class left-rail widgets, added a go-live training dashboard for sellers, and fixed OAuth signup so new users reach signup reliably and remain signed in after completing it.
- Fixed an issue where a creative created or updated with a recognized format (such as VAST video) could be rejected when assigned to a new media buy. The canonical format is now inferred automatically, so these creatives attach without an extra step.
- Localized the storefront operating instructions tab.
- Localized the storefront ad-server connection dialog.
- Localized the storefront agent connection dialog.
- Localized the storefront AI usage reporting tab.
- Localized the storefront API access settings panel.
- Localized the storefront directory card modal.
- Localized the storefront communications settings panel.
- Localize storefront settings copy for state controls, brand identity, approvals, visibility, and regional settings.
- Localized the storefront inventory source detail dialog.
- Localized storefront inventory source status tiles.
- Localized the storefront single sign-on settings panel.
- Localize storefront team management copy, invite modal text, role labels, and membership auto-join settings.
- Fixed media buys to agent-backed storefront inventory sources being rejected with a “product not hydrated for account” error. The buyer’s brand is now forwarded consistently on both product discovery and the buy, so the source resolves the same account for both legs even when account sync is unavailable.
- Storefront product discovery and composition now transparently retry the underlying inventory source on transient connection failures (e.g. a brief upstream restart) instead of immediately surfacing a “service unavailable” error. Only idempotent reads are retried, with capped exponential backoff.
2.160.0 — June 16, 2026 at 8:31 AM UTC
- Creative assets now report their actual pixel dimensions (
width,height) in the manifest response for image and video files. Uploads are validated at creation time: awarningsarray on each asset surfaces filename-vs-actual mismatches (e.g. a file named300x250.pngthat is actually 600x500) and flags unusually small assets auto-assigned as the primary creative. When a media buy targets a format with explicit pixel requirements, those dimensions are also verified at assignment time. - Added HTTP Basic Auth support for external inventory sources. Publishers can now register inventory sources that use username/password credentials by specifying
authenticationType: 'BASIC_AUTH'withauth: { type: 'basic', username: '...', password: '...' }. - Completed HTTP Basic Auth support for storefront inventory source registration, UI configuration, polling clients, and local end-to-end validation.
- Fixed create_media_buy failing with PRODUCT_NOT_FOUND (“not hydrated for account … call get_products first”) when forwarding to a pass-through sales agent. The buy now syncs and forwards the same account the get_products discovery leg established, so the source resolves the buy against the account its products were hydrated under instead of a different one.
- Localized activity feed labels and controls, including locale-aware activity timestamps and campaign budget details.
- Localized the buyer planning brief list, detail view, response cards, and sharing dialog.
- Localized proposal cards and storefront media buy approval review surfaces, including locale-aware budget and submission date formatting.
- Localized the storefront proposal queue and proposal code composition flow.
- Add a centralized seller dashboard summary endpoint and wire the Closer widget to use it for buyer brief closing analytics.
2.159.0 — June 15, 2026 at 7:03 PM UTC
- Expanded reviewed UI translation catalogs and added safeguards for new localized UI copy.
- Murph now treats portfolio seller onboarding and avails intake as explicit storefront setup flows, with checklist guidance for missing seller materials before inventory can be loaded.
2.158.0 — June 15, 2026 at 6:40 PM UTC
- A buyer sponsored into a storefront now lands on a bespoke proposal — “here’s what can do for you” — instead of a blank planning brief. A new
GET /api/v2/buyer/proposalsendpoint runs a brief-less product discovery scoped to the buyer (confined to the sponsor’s storefront for a sponsored buyer) and returns the resulting media-plan proposals, and the buyer home renders them as a card grid (plan, why it fits, placements, budget guidance). Selecting a proposal carries it into the chat to set up. Buyers with no advertiser yet, or storefronts whose agents don’t return plans, degrade gracefully to the co-branded home. - Murph can now draft a concrete avails-feed request and CSV template when seller-provided material is market context rather than actual sellable availability rows.
- Fixed “Service token with ID 0 not found” error when deleting API keys from the UI.
- Fixed product discovery returning no results from strict sales agents. Outbound get_products requests now send only the brand identity (domain and brand id), matching the behavior already applied to create_media_buy and sync_accounts.
- Storefront modular avails feeds can now preview and commit raw seller rows from CSV text, JSON text, or spreadsheet-like row objects before publishing updated availability.
- Murph now distinguishes seller market summaries from actual avails feeds and asks for real sellable inventory rows before committing modular feed updates.
2.157.0 — June 15, 2026 at 2:43 PM UTC
- Catalog sync responses and catalog listings now expose feed health, freshness, version summaries, and item-change summary fields. Catalogs can also store deterministic transform definitions that turn feed items into campaign groups, creative prompt cache keys, budget hints, and backend-inferred seller sharing plans; syncs with an active transform automatically generate a latest activation plan. Item-level catalog changes remain internal to support catalog-driven campaign, creative, and seller re-syndication workflows.
- Creative collections now fan out member creatives into campaign assignments on attach, respecting the format_kind upgrade gate. Added advertiser-scoped collection endpoints (
GET/POST /advertisers/:advertiserId/creative-collections) andowner_scopefield on collection summaries. - Added locale-aware Murph preference plumbing, reviewed core-language UI catalogs, and a glossary-aware translation workflow for seller-facing Murph actions.
- Added a storefront demand inbox: every buyer brief sent to your storefront, how your agent responded, and the commercial outcome.
GET /api/v2/storefront/intelligence-runsnow accepts abuyingModefilter (brief,wholesale,refine) and acommercialResultfilter (booked— forwarded upstream or delivering;pending— awaiting your acceptance-policy approval;rejected) so you can pull just the demand that converted, the demand still waiting on your sign-off, or the demand that didn’t — and each run carries its qualification reason and composed-product explanation. - Added a buyer MCPUI setup widget and workspace launcher for registering advertiser event sources with expert-run setup, integration mapping metadata, basic ingestion health, and alignment with the shared ADCP event taxonomy.
- Fixed the buyer Ask Murph landing page so it no longer uses seller Merchandising Agent naming.
- Fixed product discovery returning no results from sales agents pinned to AdCP 3.0. Discovery get_products calls no longer attach a discovery webhook (push_notification_config) when the client is below AdCP 3.1; results are retrieved synchronously via polling instead.
- Fixed media buy execution and account sync failing against sales agents that strictly validate the brand field. Outbound create_media_buy and sync_accounts requests now send only the brand identity (domain and brand id); brand-kit and other inline brand overrides are resolved by the seller from the brand’s published brand.json.
- Fixed Murph handing out broken ad-server credential-connection links outside of Slack. Links now always point at the configured storefront domain so the secure FreeWheel/SpringServe credential form is reachable.
- Campaign-level postal-code guardrails now merge correctly with the country-local postal area shape: the country is preserved and postal codes are no longer merged across different countries that share a postal system. Targeting a single country’s postal codes (e.g. South Africa) through a campaign guardrail now produces valid, country-scoped targeting.
- Storefront
update_media_buyis more honest when a multi-source buy only partially applies: if some sources accept the update and others reject it, the storefront now returns an error with per-source detail instead of reporting a clean success for a half-updated buy. Budget changes that the storefront cannot parse (for example a non-numeric amount) now require seller approval rather than being auto-forwarded, and a buyer’s push-notification callback config is no longer forwarded to upstream sources. - Fixed storefront media-buy updates so mutable fields are forwarded to inventory sources, material updates enter seller approval before taking effect, and pending update tasks emit terminal webhooks.
- Storefront
update_media_buynow forwards each change to the correct source instead of broadcasting the buyer’s full update to every source. Per source, the storefront keeps only that source’s packages (translated to the upstream package IDs) — each package carrying its own budget — and passes through lifecycle and flight changes (pause/resume, cancel, start/end, targeting). This fixes over-committing on multi-source media buys, where every source previously received every package. - Added an opt-in FreeWheel modular inventory source setting that attempts campaign, insertion order, and placement execution automatically while falling back to the source work queue when execution cannot complete.
- The capability gate that rejects unsupported targeting on ROUTED media buys now covers metro-area systems (
geo_metros) in addition to postal codes, and is structured as a generic per-dimension registry so future targeting dimensions are covered without bespoke wiring. Behavior is unchanged for postal and for any seller that does not declare a given dimension (fail-open). - Extended the seller dashboard spec with contract metadata, data sources, metric definitions, data status, and the Closer widget for seller brief outcomes.
- The identity-match targeting feed now accepts root-relative seller agent endpoints (e.g. platform-hosted storefronts) in addition to absolute URLs, so packages backed by hosted storefronts are no longer dropped from the feed.
- Storefront sales agents now declare postal-code targeting per country (ISO 3166-1) and translate buyer-supplied country-local postal codes into each platform’s native geo targeting. Snap and Meta read the buyer’s
geo_postal_areas(previously dropped) and emit country-scoped postal targeting; Reddit no longer advertises postal targeting it cannot honor. Declared postal support remains US-only pending per-country platform verification. - Storefront-to-storefront buying is now end-to-end: a curator storefront with an ACTIVE link can place, update, and track a media buy against a linked seller storefront’s inventory. Create/update/delivery forward in-process to the seller, the seller’s manual-approval responses are reconciled automatically, and the buyer-facing status rolls up across linked and direct sources. A reach-fence restricts the linked connection to buyer operations only, the loop/depth guard and call-time link-active recheck extend to every mutating call, and the seller is never disclosed to the buyer.
- Added seller-facing endpoints and storefront controls for modular inventory source work items.
- Improved buyer catalog refresh and activation history so feed updates show clearer downstream impact and seller delivery readiness.
- Improved buyer catalog feed visibility with recent refresh and fan-out history in catalog responses.
- Murph no longer pauses ESA product creation when a publisher domain has no
adagents.json/ AAO record. AAO publication remains a separate, optional- setup step in the business-profile flow — operators can author products
- immediately and add AAO authorization on their own timeline.
- A buyer sponsored into a storefront now enters a co-branded experience scoped to that sponsor. A new
GET /api/v2/buyer/scopeendpoint surfaces the sponsoring storefront (name, branding, channels, regions, and account status), the buyer home and shell are framed in the sponsor’s brand, and Murph speaks in the sponsor’s voice — scoping guidance and starter actions to advertising through that storefront. While an account is awaiting the storefront’s approval (or suspended), the home and Murph explain the status and steer toward setup instead of buys that can’t go through yet. Ordinary marketplace buyers are unaffected. - Storefronts can now decline buyer briefs that clearly don’t match what they sell or violate their acceptance policy, before composing products — cutting wasted composition cost and capping buyer-driven spend. Fit is judged from the storefront’s actual inventory (its packages, channels, regions, and verticals); policy is judged from its acceptance policy. If you set an acceptance policy, briefs that violate it are declined automatically. Buyers receive a standard “no matching products” response — the seller’s reasons are never exposed. Every incoming brief is recorded with its outcome (responded / declined for fit / declined for policy), filterable via
GET /api/v2/storefront/intelligence-runs?disposition=..., so sellers can see exactly which briefs they’re winning and missing. This applies to every configured storefront, and the qualifier fails open (composes) on any error so a fault never silently turns away demand. - The storefront intelligence-runs list endpoint gains a
qquery parameter for case-insensitive brief search, alongside the existingdispositionfilter:GET /api/v2/storefront/intelligence-runs?disposition=declined_fit&q=fintech. Find the demand you’re winning and missing by searching brief text and filtering by outcome. get_media_buy_deliverynow reports a real, rolled-up status for a media buy that spans multiple sources, instead of always returningpending_start. The status reflects the worst material leg — a rejected or unreachable source is never hidden behind a delivering one — and per-source problems (a refused leg, a source that could not be reached) are listed in the responseerrorsarray. When no source returns observable delivery, the call returns aSERVICE_UNAVAILABLEerror rather than zeroed totals under a misleading status.get_media_buysnow reports a real, rolled-up status for each media buy instead of always returningpending_start. A background reconciler keeps each source’s upstream status fresh, and the list folds the per-source statuses into one buyer-facing status — fail-visible, so a rejected or unreachable source is never hidden behind a delivering one. The list is cached for cheapness;get_media_buy_deliveryremains the live, authoritative current status.- Added structured buyer brand context to planning briefs and storefront proposals, and forwarded storefront product selectors through live passthrough discovery.
- Offering-based postal targeting now honors each offering’s country. Previously, postal codes supplied via an offering’s
geo_targetswere always targeted in the US — a non-US offering’s postal codes were silently mis-targeted. Offerings now carry country-aware postal areas (geo_targets.postal_areas), and the legacy country-lesspostal_codesfield is wrapped using the offering’s country (falling back to US only when no country is known). On Meta, package-level targeting supplied by the buyer is also preserved when an offering adds its own geo, instead of being dropped. - Storefront MCP connections now stay reliable across multiple server instances. A follow-up request that lands on a different instance than the one that opened the session is transparently recovered instead of intermittently failing, matching the behavior of the buyer and creative MCP surfaces.
2.156.0 — June 14, 2026 at 3:08 AM UTC
- ROUTED media buys are now rejected at execution when the selected sales agent has not declared support for the requested postal-code targeting (
geo_postal_areas), instead of silently dropping the targeting or failing with an opaque seller error. The seller’s declared postal support is read fromget_adcp_capabilities.
2.155.0 — June 14, 2026 at 12:46 AM UTC
- Added storefront acceptance policies plus creative and media-buy policy evaluation so approval workflows can distinguish definitely-on-policy, definitely-off-policy, and human-escalation cases instead of relying on generic operating instructions.
- Optimization suggestions awaiting operator approval are now automatically expired when the underlying media buy is updated. Previously, an operator could approve a suggestion only to discover at apply time that the media buy had been edited and the suggestion was no longer valid. The expiry now happens at the moment the new media buy version becomes active.
- Fixed optimization suggestion apply flow so that when a media buy is updated between when a suggestion is produced and when it is applied, the suggestion is correctly handled based on whether the content actually changed. Stale pins where the underlying configuration is identical now retarget to the current version automatically; pins where the configuration has drifted are marked as expired with a clear reason. Suggestions that pre-date this change continue to use the prior strict-version-equality check.
- Deleting a creative manifest now succeeds even when the creative is actively synced to sales agents. Instead of returning an error, the creative is archived, unlinked from any media buys it was assigned to, and the removal is synced to those sales agents.
- Your Merchandising Agent now learns which negotiation strategy actually wins deals and leans into it. Its strategy recommendation favors the posture that has booked the most for you recently — but only once there’s enough evidence to trust (at least four runs that used it, and only if it’s actually converting). Your operating instructions and a buyer’s live signals still take precedence, and the reasoning is recorded with each run so you can see why a strategy was chosen. Below the evidence threshold, the agent falls back to its existing heuristics.
- Advertiser-scoped creative, discovery, and account-sync calls now use the advertiser’s linked brand reference so downstream partners receive the resolved brand identity consistently.
- Murph now publishes reviewed brand.json updates to the AAO community registry through the ADCP SDK registry client.
- Every storefront now starts with default selling behavior: the Merchandising Agent uses your wholesale products and signals to answer briefs as best as possible from the moment the storefront is created. Operating instructions no longer appear in the storefront panel or block going live — you refine how your agent sells by coaching Murph in plain language, and the readiness check now reads “Selling behavior.” Pricing stays separate throughout: wholesale rates come from your inventory sources (your embedded or third-party sales agent), and your rate card shapes buyer-facing pricing. The version history remains available on the operating instructions tab for audit.
- The storefront detail endpoint (
GET /api/v2/buyer/storefronts/:storefrontId) now includes anadcpCapabilitiesfield exposing which AdCP operations the underlying agent declares support for. Buyers can checksupportsUpdateMediaBuy,supportsCreateMediaBuy,supportsGetReporting,supportsSandbox,extensions,protocols, and reporting delivery methods before attempting calls, without needing to call the agent directly. ThecapabilitiesCachedAttimestamp indicates when the manifest was last refreshed from the agent. - Murph and buyer agents now explicitly warn that
budget.currencyis immutable after campaign creation and must always be confirmed with the user before callingcreate_campaign. This prevents campaigns from being silently created in the wrong currency (e.g., USD when EUR was requested), which required a full campaign recreate to fix. - Fixed a bug where creating a GAM advertiser via the storefront ESA endpoint (
POST /api/v2/storefront/esa/:id/gam/advertisers/ensure) failed with a validation error on the live path while the dry-run path succeeded. The upstream service returns a numeric advertiser ID on real creation; the response schema now accepts both string and numeric IDs and coerces them to strings. - Updated Google Ads offline conversion logging to use the Google Data Manager API.
- Added modular inventory source controls for operator-confirmed avails feeds, reservations, lifecycle readiness, demo Cadent handoff preparation, booking release, and source-side work queues.
- Storefront diagnostics now live with the storefront. Each inventory source’s drill-in shows its recent ADCP calls and status changes next to its health diagnostics, so a failing source carries its evidence with it. The seller navigation slims down to chat and history: the standalone Diagnostics and Dashboard pages are no longer in the seller nav (test runs live in “Test your storefront”, change history and activity are available by asking Murph), and the conversation-history sidebar starts collapsed.
- Before your Merchandising Agent is selling, the storefront panel now shows the journey instead of a console: the header counts what stands between you and your first buyer brief (“Two things stand between you and your first buyer brief.”), each open blocker is a numbered step you can tap to fix with Murph (with consequence framing — “No sources connected — your agent has nothing to sell yet”), and everything non-blocking is tucked into a single “How your agent represents you” section. The status chip now reads “Selling” / “Not selling yet”. Once the agent is selling, the panel becomes the health dashboard as before.
- Media buy execution failures against storefront agents now preserve the structured AdCP error envelope, including
details.per_source. When every inventory source rejects a media buy, the per-source errors appear in debug output (errors[].debug.response.adcpError) instead of being flattened to a single message string. - Your storefront now prices to value, not to cost. For every brief, the Merchandising Agent sets the price from what the brief is worth to that buyer — premium format, scarce audience, advertiser type, urgency, stated budget — bounded by your wholesale floors and any ceilings you’ve set, never anchored to a historical auction-clearing percentile. The old fallback percentile is retained only for explainability and no longer sets prices; Murph no longer asks you to choose one. Explicit rate-card targets still act as a value floor the agent can exceed for higher-value briefs, and wholesale rates continue to come from your inventory sources.
- The “Watch your agent sell” card now leads with reality: when buyer demand signals are queued for your storefront, the card shows the actual brief — buyer name, audience, geo, budget — and “Answer this brief” takes it straight to Murph. With no queued demand, briefs are generated from your business profile (your channels, regions, and verticals) instead of a generic pool. Before a storefront exists, the storefront panel now shows a single action — create your storefront — and sections appear only as they become real.
- Improved the storefront Merchandising Agent screen with clearer onboarding copy, a live seller performance dashboard, and cleaner action hierarchy.
- REST error responses with a 5xx status now return a generic message (“An internal error occurred…”) instead of the underlying error detail. Internal errors previously embedded the raw error string — which can include database/driver internals — into the response body; that detail is now logged server-side only. Intentional 4xx messages (validation, not-found, conflict) and the 503 retry message are unchanged.
- Seller analytics now breaks conversion down by the negotiation strategy your agent actually used. The
show_seller_analyticspayload includes apostureConversionrollup: per-posture run count, booked count, win rate, and booked budget, plus an adherence summary comparing how often your agent followed its recommended posture and whether following it converted better. This turns the per-run strategy capture into “which strategy wins deals” — the evidence base for tuning your selling terms. - Murph’s seller starter prompts now speak in selling verbs instead of setup verbs — “See my agent handle a brief”, “Train how I sell”, “Connect what I sell”, “Is my agent ready to sell?” — and the seller chat header reads “Train the agent that sells your inventory.”
- Murph now stays in the seller’s register when things break or go deep: connection failures are summarized in plain language with an offer to write up the technical details for your developers, ad-server objects keep the names operators use (never internal identifiers), and acronyms are expanded on first use. Copy refresh from the fresh-eyes audit: the example brief on the chat home is labeled “Example brief”, and the starter chips say “Show me my latest buyer briefs” and “What can my agent sell right now?”. The panel header no longer clips its collapse button in narrow layouts.
- The Merchandising Agent panel now has a “Selling terms” section showing the enforced facts your agent prices and gates on. Under “How it prices”, each rate-card rule shows its floor / target / ceiling by pricing model, marks enforced floors (“Hard floor”) versus advisory guidance, and names the brief it applies to. Under “Reviews & approvals”, your creative-review and media-buy approval gates are shown in plain language, with a one-tap “Change approvals” action. When you have no price rules, it says so plainly — your agent prices from your sources’ rates — with a one-tap “Set selling terms” action. Wholesale rates always come from your inventory sources; these rules shape the buyer-facing price.
- The inventory-source health indicator now tells the whole truth. A source no longer reads “healthy” while its connection is failing or degraded, while nothing has ever successfully synced or been called, or while its inventory list hasn’t been pulled — each of those states now downgrades the verdict, explains itself in the status tooltip, and marks the matching row in the source’s detail view.
- Storefront sellers can now see their AI usage by model over time in a usage dashboard.
- The storefront api_call tool now supports a named
operationfield (e.g.list_partner_agents,get_storefront,create_esa_connection), matching the buyer surface. Operation mode derives method and endpoint automatically, validates path parameters before dispatch, and rejects unknown operations and unexpected path params — so agents call storefront operations by name instead of constructing raw endpoint URLs. Raw method+endpoint mode still works as a fallback. - Sellers can now see how their agent is selling, broken down by negotiation strategy. A new
GET /api/v2/storefront/seller-analyticsendpoint returns the posture-conversion rollup — per-posture run count, booked count, win rate, and booked budget, plus how often the agent followed its recommended strategy and whether following it converted better. The Merchandising Agent rail surfaces this as a “How your agent is selling” section once the storefront is live, so the answer to “which strategy wins deals” lives on a durable surface, not just in chat. - Manual-approval media buys are now visible end-to-end. Storefront operators see pending media buys on the storefront homepage (live count) and can review, approve, or reject them on the new Media buy approvals page. Buyers can see which layer a
PENDING_APPROVALmedia buy is waiting at via the newpendingAtfield (storefront,salesagent, orunknown) on campaign media buys. Executing a campaign with no media buys to execute now returnsmediaBuysExecuted: 0withreason: no_media_buys_to_executeand no longer marks the campaign ACTIVE. The execute-campaign request body now rejects unknown fields with a 400 that names them. - The seller chat home now opens with “Watch your agent sell”: a synthetic buyer brief your Merchandising Agent answers honestly from your actual setup — naming the missing supply when no inventory is connected, asking to be trained when selling rules are missing, and offering to run the brief once you’re live. “Train how I answer this” starts the coaching conversation with Murph; “Try another brief” rotates briefs, leading with the channels you sell.
2.154.1 — June 12, 2026 at 9:38 PM UTC
- Brand identity for product discovery, campaigns, and media buys is now always governed by the brand configured on the advertiser — it can no longer be set or overridden per request. Previously a
brand_manifestsent on a media buy could override the advertiser’s brand at execution time, producing a brand domain that didn’t match the one products were discovered under; valid products were then reported as unknown and the buy failed before reaching the sales agent. Media buy execution and product discovery now both resolve the brand solely from the advertiser, so the two can never disagree. Additionally, an advertiser must have a brand configured before product discovery can run or a campaign or media buy can be created: these actions now fail with a clear validation error directing you to add a brand to the advertiser first, instead of failing later with confusing errors.
2.154.0 — June 12, 2026 at 9:06 PM UTC
- Creative manifests now expose a
requires_upgradeboolean field. Legacy manifests (created without aformat_kind) haverequires_upgrade: trueand must be upgraded via the newPOST /campaigns/:campaignId/creatives/:creativeId/upgradeendpoint before they can be assigned to new media buys. Existing media buy assignments are unaffected. - Fixed optimization suggestion HIL expiry so that newer suggestions correctly supersede older pending suggestions for the same media buy, even when a media buy update created a new version between them.
- Fixed optimization-suggestion expiration so that a new suggestion only expires prior pending suggestions for the same media buy. Previously, a new suggestion on one media buy expired pending suggestions across all media buys in the campaign, leaving only one pending suggestion per campaign at any time.
- Storefront media-buy and creative approvals now surface consistently in the storefront-managed approval queue, execute against the underlying sales agent after approval, and send buyer ADCP webhooks when queued approvals resolve.
- Reframed the storefront setup panel around your Merchandising Agent. The panel header now shows how far the agent is from going live and names the next blocker, the readiness section is a blocker-led go-live checklist, brand identity and business profile are combined into a single “About your business” section, and sandbox test plans are now “Test your storefront”. Section summaries lead with what needs attention (for example “1 of 2 sources needs attention”) instead of raw counts. Every empty state now offers a one-click action — Connect inventory, Run a test brief, Build my profile, Draft my instructions — that drops a ready-made prompt into the Murph composer, and suggested prompts stay available above the composer mid-conversation instead of appearing only on a new chat.
- Media buys forwarded through a storefront to its inventory sources no longer fail client-side schema validation on creative asset values the seller would accept — most notably VAST tag URLs containing
[MACRO]placeholders (e.g. IAS[OMIDPARTNER]), which previously failedformat: "uri"validation before the request ever reached the source. The source now adjudicates its own request schema; validation issues are logged as warnings. - TikTok adapter now preserves the upstream HTTP status and response body when a request fails. Gateway errors and timeouts previously collapsed into an opaque “Upstream request failed” with no detail; they now surface the real HTTP status and a body snippet so failures are diagnosable.
- TikTok adapter now logs the upstream error code, message, and request ID when TikTok rejects a request with a structured error (e.g. budget below minimum, invalid parameter, account/permission issue). Previously these rejections were masked to a generic “Upstream request failed” with no detail in logs, making the actual cause impossible to diagnose.
2.153.0 — June 12, 2026 at 6:00 PM UTC
- Currency pickers (advertiser primary currency, planning brief budget) now offer every ISO 4217 currency instead of a fixed list of ten.
- Campaign currency now defaults to the advertiser’s primary currency when not specified on create (instead of hard-defaulting to USD); an explicit budget currency still takes precedence. Contract rate cards no longer constrain a campaign’s currency — only product pricing must match the campaign currency. An advertiser’s primary currency can now be changed at any time, even when existing campaigns use a different currency (each campaign keeps its own currency); the previous block has been removed. The advertiser creation form now prompts for the primary currency (defaulting to USD) so it is set explicitly during setup.
2.152.0 — June 12, 2026 at 5:08 PM UTC
- Fixed a bug where package budget and bid allocations were not persisted locally after an optimization suggestion was applied. Agents that don’t return
affected_packagesin theirupdate_media_buyresponse left the optimizer with stale baseline data for future runs. - Improved Google Ad Manager buyer-routing diagnostics for storefronts, including safer advertiser-create recovery guidance and warnings when an advertiser sync completes without reporting how many advertisers were retrieved.
- The Terms of Service update prompt now requires admins to tick a confirmation checkbox before the “Agree” button becomes active, so accepting updated terms on behalf of an organization is a deliberate two-step action rather than a single dismiss-the-popup click.
2.151.0 — June 12, 2026 at 2:40 PM UTC
- Adds an advertiser-level creative library. Creative manifests can now be created directly under an advertiser (without requiring a campaign), stored as reusable masters, and assigned to campaigns via new endpoints:
POST /advertisers/:id/creatives/create- create an advertiser-level creative masterGET /advertisers/:id/creatives- list the advertiser’s creative libraryPOST /advertisers/:id/creatives/:creativeId/campaigns- assign a master to a campaignDELETE /advertisers/:id/creatives/:creativeId/campaigns/:campaignId- remove a campaign assignment- Existing campaign-scoped creative endpoints are unchanged.
- Child accounts can now create campaigns using their parent organization’s contract pricing. Previously, creating a campaign from a child account failed with “No active contract found for customer” even when the parent organization had an active contract.
2.150.1 — June 12, 2026 at 1:38 PM UTC
- Capability-mismatch errors (
CAPABILITY_NOT_SUPPORTED) from update operations are now classified ascorrectableand include suggestions naming the specific actions the sales agent does not support (for exampleupdate_pacing), so you can remove the unsupported field(s) and retry. Previously they were classified astransientwith no guidance, which could prompt repeated identical retries of a request that can never succeed as-is.
2.150.0 — June 12, 2026 at 1:21 PM UTC
- Fixed storefront inventory source assessments so AdCP 3.0 agents that support signals are probed with a schema-valid signals discovery request instead of being marked unsupported before a request is sent.
- Fixed product discovery returning zero products from storefronts whose connected inventory source requires a buyer account. The buyer account is now passed through when discovery runs against an in-process storefront agent.
- Improved buyer campaign creation guidance so explicitly requested budget currencies are preserved when campaigns are created.
2.149.0 — June 12, 2026 at 2:38 AM UTC
- Added embedded sales agent signal management endpoints and an interactive widget for authoring mapped and composite signals.
- Allowed advertiser creation to register a reviewed brand identity when registry enrichment has no brand data.
- Buyers can now inspect the AdCP capability manifest for any storefront via
GET /api/v2/buyer/storefronts/:storefrontId/capabilities. Returns the supported operations, account resolution mode, billing types, and raw capability payload for each source agent — useful for diagnosing why an operation likeupdate_media_buymay be gated.
2.148.1 — June 11, 2026 at 10:12 PM UTC
- Fixed format_option_ref to use the AdCP 3.1 scope-discriminated union. Now accepts
scope:"publisher"(requirespublisher_domain) andscope:"product"(forbidspublisher_domain). Legacy flat input without ascopefield continues to work — scope is inferred frompublisher_domainpresence.
2.148.0 — June 11, 2026 at 8:40 PM UTC
- Clarified and implemented campaign-level budget reductions for executed media buys: lowering a campaign budget now proportionally reduces live package budgets when needed, while explicit package amounts remain available through the campaign update operation.
2.147.0 — June 11, 2026 at 6:44 PM UTC
- Operating instructions now make their effect clear during storefront setup. The storefront panel keeps a plain-language “what this does” line on the active instructions — that these rules drive every buyer request to decide what it offers, prices, and rejects — instead of collapsing to a bare version/status once a version is live. Murph also states the effect and next step while showing the assembled draft, before asking to activate.
- Tidied the embedded sales-agent catalog view in the storefront panel so its create-product and add-signal actions read as a consistent, matched pair.
- Fixed media buy pacing and budget queries to exclude pending update proposals, ensuring calculations use only the current active version of each media buy.
- Fixed a bug where Murph would abandon the GAM inventory-source provisioning flow after the operator confirmed the service-account grant. Murph now calls the provisioning endpoint immediately on confirmation instead of stopping the flow.
- Murph’s inventory selector widget now hands selections to chat without
- requiring a product name up front. After you click “Send selection to
- Murph,” Murph proposes a sensible default name based on your publisher
- and selectors and asks you to confirm or rename before validating or
- creating the product. Empty selection now shows a clear next-step
- prompt instead of a disabled form.
- A storefront can no longer be opened for transactions when it has no products available, so buyers only see “Active” storefronts they can actually buy from. Storefronts whose product availability cannot yet be confirmed are unaffected.
2.145.0 — June 11, 2026 at 3:14 PM UTC
- Added creative collections for grouping saved creatives and source assets, plus a bulk creative update operation for previewing and applying saved creative changes with canonical click-through URL updates that refresh creative tracking metadata.
- Allowed buyers to connect multiple provider accounts for the same official adapter storefront, such as separate Snap business accounts.
- Reducing campaign budget and active media buy budget in the same request now works correctly. Previously the validation checked the campaign budget against current allocations before applying the media buy changes, causing atomic reduce requests to fail with INSUFFICIENT_MEDIA_BUDGET even when the new budgets were consistent.
- Fixed an inventory-selector search error that affected storefronts on SpringServe (and would have affected any adapter whose selectors carry null
name,path, orstatus). Previously the response parser rejected the upstream payload as malformed; it now accepts the documented contract shape so SpringServe operators can browse cached selectors and author wholesale products. - Storefront inventory-source views no longer surface an embedded sales agent connection that has no ad server attached (and was never provisioned) as a separate source. These incomplete connections previously rendered as a second “Embedded” card next to the real ad-server connection — reading as a confusing duplicate — and inflated the inventory-source count and health summary. Embedded connections that have an ad server attached continue to appear, including ones that are still provisioning or have failed, so genuine setup work stays visible.
- Improved advertiser setup guidance so agents research brand domains before asking follow-up questions and avoid unnecessary optimization-mode prompts.
- Sped up the buyer storefronts list (
GET /api/v2/buyer/storefronts). Adapter-connection status is now resolved only for the storefronts on the requested page, so response time no longer grows with the total number of adapter storefronts a buyer has accumulated. - Storefront cards now show the status chip in the footer next to the “Visit website” action, giving the brand name the full card width so longer titles no longer wrap awkwardly.
2.143.0 — June 11, 2026 at 3:28 AM UTC
- Expanded the buyer Murph workspace rail with campaign and reporting prompt actions alongside creative and asset context.
- Buyer MCP API calls now mirror additional REST routes and filters, including campaign product lookup, data delivery credential revalidation, and measurement record date/geography filters.
- Improved creative-session MCPUI review data so buyer agents can render source assets, processed renditions, and shared creative review widgets more consistently.
- Expanded the buyer Murph workspace rail with creative, audience, catalog, and event prompt areas for advertiser setup and iteration workflows.
- Prevented discovery product selections from reporting success when the request is bound to a different campaign discovery session.
- Fixed Murph customer switching during multi-customer admin conversations so scoped writes can recover from customer ambiguity.
- Hid storefront sandbox test runs from the buyer creative workspace so the rail starts with creative work and advertiser assets.
- Murph customer list tools now use server-side filters, larger default pages, and explicit pagination metadata for advertiser, campaign, and sales-agent audits. Buyer advertisers can also be filtered by linked partner account before pagination.
2.142.0 — June 10, 2026 at 10:26 PM UTC
- Added the reactivate-campaign endpoint to the buyer API reference and made it callable as the
reactivate_campaignnamed operation.POST /api/v2/buyer/campaigns/{campaignId}/reactivatereactivates a paused campaign and cascades to its paused media buys, returning the per-media-buy outcome. Previously this endpoint existed but was undocumented and could not be invoked through the named-operation path. - Added clickable asset URLs, copy actions, and a gallery view to buyer creative asset management.
- Made Murph’s agent call trace control a compact footer icon instead of a full-width button below each message.
- Fixed formatted creative previews so they no longer reload the raw preview URL as a fallback.
2.141.0 — June 10, 2026 at 8:43 PM UTC
- Added an embedded sales agent inventory browser for searching, expanding, selecting ad-server selector hierarchies, and drafting wholesale products with observed ad sizes.
- The buyer storefront detail response (
GET /buyer/storefronts/:storefrontId) now reports a single storefront-level connection status instead of a per-sourcesources[]array. Each storefront returnsconnected(ready to transact),requiresCredentials(the buyer must register credentials first), andcustomerAccounts(the buyer’s registered accounts for the storefront, deduped across sources). Credentials are still registered against individual sources. - Improved Murph creative generation workflows with connected creative-adapter discovery, richer draft/refine/finalize guidance, locked asset and rendition handling, creative workspace previews, and current default image generation models.
- Scoped the Murph creative workspace brand and asset views to the selected advertiser.
2.140.0 — June 10, 2026 at 5:48 PM UTC
- Storefront operators can now invoke ADCP protocol tools directly on connected seller agents via
POST /api/v2/storefront/agents/{agentId}/invoke. Supported tools:get_products,create_media_buy,update_media_buy,get_media_buys,get_media_buy_delivery,get_adcp_capabilities. Use this to drive deal validation flows and test agent integrations end-to-end.
2.139.3 — June 10, 2026 at 4:30 PM UTC
- Fixed pacing period packages submitting a past start time when a period’s start date has already begun. The package start time is now clamped to the current time, enabling same-day execution.
- Buyer agent lookup and media-buy creation now reject a storefront’s underlying inventory-source agent. Buyers transact with the storefront, which routes to its sources; the source agents are not addressable directly.
- Product discovery now resolves inventory exclusively through storefronts. Buyers transact with the storefront, which routes to its underlying sources, instead of addressing those sources directly. Discovered products are attributed to the storefront that surfaced them.
2.139.1 — June 10, 2026 at 1:28 PM UTC
- Murph now surfaces the correct endpoints for browsing GAM ad units and placements when operators ask how to search inventory selectors on an ESA. Previously,
ask_about_storefront_capabilityreturned no guidance for selector search, causing 404s on incorrect paths.
2.139.0 — June 10, 2026 at 12:38 PM UTC
- Creative sessions now track derived asset renditions for locked product assets, including transparent cutouts and thumbnails, while preserving the original source asset.
- Murph can now compare uploaded or linked brand artifacts against current AAO brand.json state, upload logo images to AAO review, preview proposed updates, and publish confirmed brand.json updates to AAO for verified storefront operator domains.
- Fixed ESA connections not triggering initial reporting, pricing/availability, and signal coverage syncs after creation. These data streams now start automatically when a new embedded sales agent connection is provisioned.
- Fixed
GET /campaignsreturning 500 when any campaign in the list had an end date on or before its start date. The date-ordering validation is now applied only on create and update requests, not when reading persisted campaigns. - Murph now gives tighter, more scannable replies during multi-step flows like campaign setup: it leads with the decision you need to make instead of re-stating context it already covered, and keeps each turn focused on one thing.
- Surface embedded sales agent creative-format discovery errors instead of returning an empty format catalog when discovery is unavailable.
- Embedded sales agent signal listing now surfaces upstream failures instead of silently returning an empty list. Previously any error while fetching signals was swallowed and shown as “no signals”, which could make a populated signal catalog look empty. Genuine “not found / not wired” responses still degrade to an empty list.
2.138.0 — June 9, 2026 at 10:16 PM UTC
- Fixed an issue where pacing period dates on draft media buys could not be modified, even though draft buys have never been submitted to a publisher.
- Ask Murph’s side panels now adapt to the window width. As the window narrows, the conversation rail collapses to a slim strip first, then the state rail — each expanding into a panel that floats over the conversation when opened, instead of squeezing it. Wide windows keep both rails docked side by side; narrow windows stack the panels into a single column.
2.137.0 — June 9, 2026 at 7:55 PM UTC
- Refreshed the buyer test-runs rail in Ask Murph to match the storefront sandbox-test layout: scan the run list with at-a-glance status icons, then click a run to drill into its full diagnostics — execution trace, agent calls, and a copyable diagnostic trace. Failed or blocked runs can be sent straight to the chat composer for help.
- Improved creative session planning so image, audio, and video adapters expose generation strategy, composition strategy, and native capability metadata, with cleaner evaluator selection for modality-specific creative review.
- Creative sessions can now carry locked brand assets such as logos from advertiser brand data or chat uploads through draft, refinement, preview, and finalization.
- Property list creation with large domain counts no longer intermittently times out when the AAO registry is slow. The registry lookup phase is now bounded to 45 seconds; when that limit is reached, domains are classified as unresolved (the same behaviour as when the registry is unavailable).
- Storefronts that cannot serve products due to a missing operating-instructions ruleset are now automatically paused and the operator is notified. Buyers see “This storefront is temporarily unavailable” instead of an internal configuration message.
2.136.0 — June 9, 2026 at 4:54 PM UTC
- Added a Murph diagnostics workspace for test runs, third-party agent debug calls, and account change history.
- Audio creative sessions now preserve requested AudioStack ad duration/language, allow ElevenLabs voiceover drafts without requiring a separate image-generation key, and keep draft preview links stable across API instances.
- Fixed external signals catalog probes so AdCP 3.0 sellers are not sent unsupported wholesale signals requests.
- Keep the Ask Murph chat composer focused after sending a message, so you can keep typing without clicking back into the input.
- Murph now treats staying in character as a hard rule. When a tool fails, a validation step errors, or the customer must supply inputs Murph doesn’t hold, it states the limitation in Interchange terms and asks for what it needs instead of stepping back to describe its underlying model or deny being Murph.
2.135.0 — June 9, 2026 at 1:53 PM UTC
- Added a buyer creative iteration workflow with draft variant galleries, natural-language refinement, linked asset preservation, staged evaluator checks, creative previews for image/video/audio assets, and finalization into campaign creative manifests.
- Creative sessions now plan draft target formats and required manifest assets from a plain brief, can start AudioStack draft audio variants without raw adapter JSON, and treat fal.ai as the creative provider while using transformers such as FLUX for model-family selection.
- Buyer-stack sandbox test runs resolved by storefront name are now recorded against their storefront, so they appear in that storefront’s test history instead of being saved without a storefront.
- Corrected the discovery selected-products response schema: the per-product price field is now documented as
bidPrice(the value the API actually returns) instead ofcpm. The wire response was alwaysbidPrice; only the schema and generated reference were mislabeled. - Murph now always replies with a clear message when it can’t complete a request. Previously, if Murph ran out of tool steps mid-task (for example, while repeatedly probing for data that wasn’t available), it could return a blank “no answer” response and the user had to ask again. Murph now makes a final pass to explain what it found and why it’s stuck, falls back to a plain-language message if it still has nothing to say, and stops probing failed calls sooner so it spends its effort on a useful answer.
- Murph now offers publishers a faster path to going live. As soon as an ad server is connected, Murph can propose a set of run-of-site starter products — one per authorized site and creative size, with no targeting — that are sellable as-is as a non-guaranteed CPM auction, surfacing the ad server’s pricing guidance, and frames targeted packages, curated bundles, and guaranteed deals as later steps to grow revenue rather than go-live requirements.
- Storefront sandbox test plans now show every test run for that storefront, scoped per storefront instead of per signed-in user. Operators on the same account now see each other’s test runs, and a storefront’s drawer no longer mixes in runs from other storefronts on the account.
- Murph can now retrieve storefront catalogue and embedded sales agent wholesale product lists through the storefront API tool.
2.134.0 — June 8, 2026 at 10:18 PM UTC
- Fixed BYOK creative-family storefronts so ElevenLabs and Veo expose usable audio and video creative formats.
- Fixed
PayloadTooLargeError(413) onget_productswebhook callbacks. Seller product catalogs can exceed the previous 64KB body-size cap; the limit is now 5MB forget_productsand remains 64KB for all other task types. - Fixed generated creative manifests so image, audio, video, text, and URL assets include ADCP-required asset type metadata.
- Fixed generated creative manifests so text and URL assets include required delivery metadata.
- Fixed an issue where extra creative assets (not declared in a publisher’s format spec) were included in media buy submissions, causing publisher validators to reject the request.
- Fixed create_media_buy payloads for fixed-price CPM products to include an impressions count derived from budget and CPM rate.
- Removed unused incrementalityTestingEnabled field from advertiser measurement configuration.
- The storefront panel now surfaces sandbox buyer test-run diagnostics. Each run lists its status and a step-by-step execution trace, and you can drill into a run to see per-agent get_products results — including the upstream request and response summary for each agent. When a run fails or is blocked, an “Add to chat” shortcut sends a prefilled prompt (the failed steps and any suggested next actions) into Murph chat so you can resolve it without retyping the diagnostics.
- When a seller rejects a media buy update because it falls outside the original quote envelope, the error is now logged with the specific field(s) that triggered the rejection and actionable recovery guidance.
- Publishers can now declare base template format IDs (e.g.
display_html,video_vast) on their products and buyers’ sized creatives (e.g.display_300x250_html,video_vast_30s) will be correctly matched and assigned. Previously only exact format ID matches were accepted.
2.133.0 — June 8, 2026 at 2:17 PM UTC
- Added webhook callbacks for adapter-hosted creative review status transitions.
- Add storefront adapter support for Gemini, OpenAI, FLUX, Veo, and ElevenLabs creative generation families.
- Added MCP endpoints for family-filtered creative generation and preview tools.
- Buyers now land on the Ask Murph chat experience when opening their home page, keeping the same URL. Accounts without Ask Murph enabled continue to see the existing buyer home.
- Fixed embedded sales agent (ESA) product authoring so validation failures and product lists are reported accurately. A failed product validation now surfaces the specific offending field(s) instead of an opaque error, and the product list no longer renders empty when the upstream response can’t be read — it now reports a clear “couldn’t load” error so a real fault isn’t mistaken for “no products yet”.
- Fixed Murph occasionally rendering its closing question merged into the last bullet of a list instead of as its own line.
- Media buy creative updates now send inline package creatives to sales agents that do not support creative library sync. For library-only sellers, creative sync failures now fail the update synchronously instead of continuing with local-to-seller creative state drift. Malformed creative format agent URLs are rejected before inline creative delivery.
- Storefront adapter OAuth metadata now points developers to the agentic-api adapter documentation.
- Added storefront API controls for inspecting modular inventory source setup state and updating non-secret module configuration.
2.132.0 — June 5, 2026 at 7:00 PM UTC
- Added a seller-side preview discovery endpoint so storefront owners can test how buyer agents respond to a brief before going live.
- Fixed Murph losing access to buyer write tools (create advertiser, create campaign) mid-conversation when the router classifies short affirmative messages (“yes create it”, “go ahead”) as knowledge-only. Buyer API tools now remain available for any turn that follows a turn where they were already successfully used.
- Fixed product validation during campaign execution blocking media buy creation when sales agents return non-deterministic product IDs across calls. Products are now trusted as valid until their expiration date once discovered, eliminating the re-query that caused spurious “product not found” errors.
- Creative manifests now accept
format_kind(AdCP 3.1 canonical format kind, e.g.image_carousel) as an alternative toformat_idwhen creating or updating a manifest. Also addedformat_option_refto pin a manifest to a specific product format option viacapability_id, andindustry_identifiersto attach Ad-ID, ISCI, Clearcast clock, or IDcrea identifiers. All three fields are returned in manifest responses. - Format spec lookups now correctly handle parameterized (template) format IDs such as
{id: "display_static", width: 300, height: 250}. Dimension and duration parameters are applied as asset slot requirements in the resolved spec, and different parameterizations of the same template get distinct cache entries so validation results are accurate per variant. - Exposed managed GAM advertiser search, ensure, and default selection operations through the storefront MCP API so sellers can complete buyer-routing advertiser setup from chat.
- Data Delivery Outputs now substitute date placeholders in object-store path prefixes.
{YYYY},{MM},{DD}, and{HH}are filled from the delivery period start (UTC) and{DATA_DELIVERY_TYPE}from the Output’s data type, so a prefix likelld/{YYYY}/{MM}/{DD}/{HH}/{DATA_DELIVERY_TYPE}/writes tolld/2026/06/03/14/IMPRESSIONS/. Previously these tokens were written literally. - A
pathPrefixthat contains an unsupported placeholder (for example{YYYYMMDD}or{yyyy}) is now rejected when the Output is created or updated, instead of being silently written into the object key. Any text that is not a brace-delimited placeholder is still used verbatim. - The format detail endpoint (
GET /formats/:agentUrl/:formatId) now returnscapability_idalongsideformat_id. Use this value inbuild_creativeorPackageRequest.capability_ids[]to target a specific format option on a product.
2.131.0 — June 5, 2026 at 1:14 AM UTC
- Bumped the Storefront MCP AdCP SDK integration to include the latest task polling and authorization error behavior.
- Fixes an issue where storefront adapter media buys would fail after pod restarts when scoped product IDs couldn’t be resolved to their product config.
- Enabled async completion webhooks for storefront inventory source product discovery.
- Fixed submitted product discovery polling so account-scoped inventory sources can return completed get_products results.
- Improved third-party inventory discovery so async product lookups can register callbacks and complete reliably with AdCP 3.0 seller agents.
- Child customers now inherit alpha access over MCP when their parent organization is enrolled. Previously the MCP tool-listing and execution gates only matched a customer’s own ID, so child accounts saw an empty tool list and “access denied” even when their parent was opted in — REST and the web app already honored this inheritance.
- Fixed media-buy product validation so account-scoped sales agents receive advertiser account context when products are revalidated before execution.
- Fixed
refresh_agent_capabilitiesMCP tool surfacing a garbled error message when the remote agent is unreachable. The tool previously doubled the “Failed to refresh capabilities:” prefix; the message now surfaces cleanly. - Fixed a crash on the storefront Intelligence tab where the page failed to load with “Something Went Wrong” for runs that were skipped or that listed matched products.
- Send campaign creatives inline when creating media buys so sellers without a creative library can transact from buyer workflows.
- Added a Dashboard view to Ask Murph for storefront operators. The sidebar now offers a “Dashboard” entry that swaps the chat column for a tabbed surface — Overview, Reporting, Activity, and Merchandising engine — without leaving Murph, while the conversation sidebar stays in place.
- Updated the AdCP SDK used by buyer and storefront integrations to 9.0.0-beta.24.
2.130.0 — June 4, 2026 at 6:05 PM UTC
- When connecting Google Ad Manager, Murph now explains what access Scope3 needs, what it will not do, and what the granted role allows, then asks for explicit consent before walking a publisher through granting access to their network.
- Fixed access token cookie expiry being set to 1 hour regardless of the token’s actual lifetime. The cookie now expires when the JWT does, preventing unnecessary session interruptions for long-lived tokens.
- Wait for async product discovery results from third-party inventory sources before falling back or returning no products.
- Fixed credential rotation so stale credential secret references can be replaced when the existing secret cannot be updated.
- Fixed the assistant chat not scrolling to follow new messages when a conversation is started fresh. Auto-scroll now engages as soon as the first message is sent, keeping the latest reply and the “writing it up” indicator in view.
- OAuth token exchange and refresh now delegate to adapter-provided methods when available, enabling TikTok and other providers with non-standard OAuth flows. TikTok is now a refresh-supported provider.
- Flight date updates (start and end time) on active media buys no longer require seller pre-approval. The update is still dispatched to the seller via the normal ADCP flow.
- The assistant chat now keeps the latest message in view as you send and receive messages, automatically following the conversation. When you scroll up to read earlier messages it stays put instead of yanking you down, and a control lets you jump back to the latest. Auto-scrolling respects your reduced-motion preference.
- Multi-day delivery reports now produce correct per-day, per-package metrics in delivery reporting. Previously a report covering several days collapsed its package metrics onto a single day; reporting timeseries now attribute each day’s spend and impressions to the correct date.
- Refreshed the storefront cards to a clean, consistent look. Every card is now the same light surface with a thin brand-color accent on top, so a directory of storefronts reads as one cohesive set instead of a patchwork of differently colored headers. Each logo sits on a tile chosen to contrast it — dark or colored logos on a clean white tile, light/knockout logos on a dark tile drawn from the brand’s own colors (e.g. a white wordmark on the brand’s signature color) — so logos never wash out. Whether a logo is light or dark is resolved once when the brand is looked up — from the
brand.jsonlogos[].backgroundfield, the logo’s color tags (light/dark), or its filename — and persisted on the storefront, so cards render instantly with no per-card image processing.
2.129.0 — June 4, 2026 at 1:48 AM UTC
- Buyer storefront listings now include each storefront’s coverage
regionsalongsidechannels, so buyers can see and filter the marketplace by region.
2.127.3 — June 3, 2026 at 10:55 PM UTC
- Fixed adapter storefront product discovery so returned products remain valid when executing media buys for the selected provider account.
- Fixed routed adapter storefront execution so scoped products discovered through adapter storefronts can be purchased without being rejected by repeat product validation.
- Allow adapter storefront sales agents to execute routed media buys without requiring legacy operator-auth flags.
- Fixed adapter storefront MCP calls so buyer-connected provider accounts are passed through to sales adapters.
- Fixed campaign execution so selected product budgets are constrained to the campaign’s remaining media budget after fees.
- Fixed
GET /campaigns/:idreturning duplicatemediaBuyRefsentries and staleoptimizationGoalswhen a media buy had both an ACTIVE and PENDING_APPROVAL version due to SCD Type 2 versioning. The response now de-duplicates bymedia_buy_id, preferring the pending version which reflects the most recent buyer-requested state. - Fixed routed campaign execution for adapter-backed storefronts so buys dispatch through the storefront adapter with delegated provider authorization.
- Prevented storefront-backed media buy status refresh from reporting spurious upstream agent URL errors.
- Fixed storefront
sync_accountsdry-run responses so clients receive the expected structured result. - Fixed third-party storefront inventory sources so buyer account sync and account-scoped product discovery use the submitted natural-key account instead of upstream account discovery.
2.127.1 — June 3, 2026 at 4:58 PM UTC
- Improved error propagation in the account-switch flow: internal errors now preserve their original cause for easier diagnosis, and creating a child account now correctly returns a 500 instead of an empty response when user-info retrieval fails after account creation.
- Database circuit-breaker errors now return HTTP 503 with a
Retry-Afterheader instead of HTTP 500, and no longer trigger spurious GitHub error reports. - Fixed storefront cards on the Browse storefronts page briefly rendering in the default palette before swapping to each storefront’s real branding. Cards now show a loading placeholder until branding resolves.
2.127.0 — June 3, 2026 at 4:38 PM UTC
- Connections are now accessible from Account Settings in the buyer UI. OAuth-capable providers no longer show a redundant bearer token option.
- Fixed product discovery for BYOK adapter storefronts (Snap, Meta, etc.) returning zero results. The buyer’s connected provider credential is now correctly resolved and forwarded when discovering products across adapter storefronts.
- Storefronts backed by a third-party sales agent no longer require an operating-instructions ruleset to return products. When no ruleset is active, these storefronts now pass the sales agent’s catalog through directly instead of returning a
composition_pendingerror — matching the behavior already in place for embedded sales agents. - Fixed TikTok OAuth authorization URL to use
app_idparameter instead ofclient_id, resolving the “app_id: value is required but missing” error when connecting TikTok from the buyer connections page. - Ask Murph now lets you keep typing while a reply is still streaming. Follow-up messages you send mid-reply are queued and delivered one at a time as each turn finishes, so you no longer have to wait for an answer before lining up your next question. Queued messages show as pending bubbles and can be removed before they send.
- Storefront operators can now refresh a sales agent’s cached capabilities themselves via
POST /api/v2/storefront/agents/{agentId}/capabilities/refresh(also available through the storefront MCP). This previously required platform admin access. Use it when an agent changes what it advertises (for example, whether it requires operator credentials or which billing modes it supports) and the cached state hasn’t caught up yet. Sellers can only refresh agents their own storefront owns.
2.126.0 — June 3, 2026 at 2:31 PM UTC
- Added compatibility handling for media buy delivery reporting webhooks that are sent without an ADCP task envelope.
- Adapter storefront inventory is now identified as ROUTED-only and rejected when used with DECISIONED campaigns.
- Added an account analysis MCP tool for adapter-backed storefronts, including structured findings, recommendations, and an interactive analysis viewer. The tool uses delegated storefront adapter connections for provider auth, and Spotify is available as a wired storefront adapter provider.
- Added
adapterProviderTypefield to the buyer storefront list response, indicating the adapter platform (e.g. “meta”, “tiktok”) or null for non-adapter storefronts. - Buyer storefront browse now filters by status, channel, and region server-side.
GET /api/v2/buyer/storefrontsaccepts three new optional query params:status(configuring|transacting|archived),channel(an ADCP channel code such asdisplay,olv, orctv), andregion(a region code such asEMEA,NORAM, orAPAC), returning only matching storefronts. On the browse page, the status, channel, and region filters are now populated from known option sets and drive the query directly, so they render fully on first paint instead of appearing only after the storefront cards finish loading. - Delivery webhooks now deduplicate on idempotency_key, preventing duplicate processing when sellers retry delivery reports.
- Murph seller analytics now returns historical performance and strategy signals, and product composition can use recent storefront outcome history to tune built-in negotiation defaults.
- Added seller recommendation signals to Murph seller analytics.
- Products now surface
formatOptionsin discovery responses when the sales agent publishes AdCP 3.1format_options[]declarations. Each entry carries aformat_option_idthat buyers can reference viaformat_option_refsincreate_media_buyto select a specific format option. - Added durable storefront adapter connections so server-side workflows can use delegated provider credentials without client-held tokens.
- AM-1287: Derived managed ad-server operational health from the upstream tenant status feed, and treated local provisioning state as lifecycle bookkeeping rather than request-readiness.
- Added Spotify as a supported expert-run adapter provider for Storefront configuration.
- Fixed adapter storefront discovery so connected adapter storefronts can be used from buyer-agent product discovery workflows.
- Added buyer-facing provider connections for official adapter storefronts, including browser handoff URLs for OAuth providers and bearer-token setup for direct adapter credentials.
- Documented the storefront source graph architecture, clarified the Storefront routing boundary, and exposed storefront-level routing metadata plus adapter OAuth discovery for expert-run adapter storefronts. Linked storefronts and embedded sales agents are private Chef sources, not Storefront routing modes.
- Expanded Murph seller analytics with buyer-level negotiation conversion, monthly seasonality signals, and richer guidance for storefront negotiation strategy.
- Fixed third-party sales-agent calls (get_products, create_media_buy) failing with a spurious ADCP error. Activity capture is now best-effort: when a source has no entry in the shared agent registry, the activity is skipped rather than failing the underlying call.
- Fixed the adapter OAuth success page close button so it works under the deployed content security policy.
- Fixed adapter OAuth authorization so allowed localhost callback URLs can be used with providers that auto-register OAuth clients.
- Fixed a race condition in Ask Murph where clicking “New Chat” while a response was streaming would be overridden by the completing stream, leaving the user in the old conversation instead of starting fresh.
- Fixed buyer agent access to official adapter storefront connection management.
- Improved Buyer MCP tool discovery so agents can reliably find and use the API call tool after selecting an account context.
- Fixed carousel creatives being rejected during sync when the format spec declares only a repeatable group (no individual asset slots). The asset builder was incorrectly falling back to generic type-based keys (
image,image_2, etc.) alongside the correctcardsarray, causing the pre-sync asset validator to flag those keys as unrecognized and block the request. - Fixed a 500 (
Failed to browse products) in product discovery when a sales agent returns a product card without a format id. The product-card projection now tolerates a missingformat_idinstead of throwing, matching the guarding already used elsewhere in the same path. - Fixed list tables showing a contradictory “Page 1 of 0” pager when there were no results. The pagination footer is now hidden whenever a list is empty, across the campaign creatives page and all tables built on the shared entity table (storefront, proposals, advertisers, connections, discover supply, and others).
- Fixed storefront media buys so products backed by embedded sales agents can be bought and have creatives synced end to end.
- Fixed Storefront adapter OAuth authorization so allowed redirect URIs can be used reliably after server restarts or across multiple API pods.
- Improved storefront product pricing so audience signals do not incorrectly apply unrelated inventory rate card rules to premium packages.
- Fixed a budget error that blocked executing a campaign whose selected products carry no explicit per-product budget (for example a single discovered product executed directly). Such products now default to a share of the campaign’s post-fee media budget rather than the fee-inclusive total, so they no longer overshoot the media budget and get rejected during execution.
- Product discovery is now resilient to a single sales agent returning a malformed response. Previously, one agent’s unparseable products (for example an invalid format list) could fail the entire discovery request with a 500; now the offending agent is skipped and recorded, and the remaining agents’ products are still returned.
- Updated the buyer storefront browse copy: renamed “Browse the Interchange” to “Browse storefronts” with the subtitle “Discover who sells on the Interchange.” on both the home-page section and the full storefronts page.
- Renamed the embedded-sales-agent surface from “PSA” to “ESA” across the storefront API. Storefront REST routes move from
/api/v2/storefront/psa/...to/api/v2/storefront/esa/..., the inventory-sync webhook moves from/webhooks/psa-sync/...to/webhooks/esa-sync/..., and the response/schema names (PsaConnection,PsaTenantStatus,PsaSyncHistoryResponse, etc.) are renamed to theirEsa...equivalents. The unrelated Platform Services Agreement (“PSA”) used in terms-of-service acceptance is unchanged. - Fixed adapter storefront product discovery routing when existing storefront agent rows had stale MCP endpoints.
- Storefronts now compose third-party sales-agent inventory into their own branded catalog, alongside embedded sources. A connected third-party agent’s products are warmed, offered to Chef composition as single-source products, and exposed pass-through — all routable on
create_media_buy. If composition is briefly unavailable, the storefront still serves each source’s own products rather than returning empty. - Storefront MCP sessions now use the AdCP SDK platform handler at the existing
/storefront/:platformId/mcpendpoint. Storefront discovery, buyer session binding, and config-derived capabilities are preserved. Mutating Storefront tools now advertise and enforce AdCP idempotency with a 24-hour replay window, SDK request/response validation is strict, and buyer-visible SDK tasks are persisted in Postgres for restart and cross-pod polling safety. - Storefront source diagnostics now report per-source health. Each entry in a storefront’s readiness
sourceDiagnosticsincludes ahealthobject —status(healthy/degraded/unhealthy/unknown), the last error message and code, and the last error / success / check timestamps — so operators can see when an upstream inventory source last responded and why a read degraded.
2.125.0 — May 30, 2026 at 6:45 PM UTC
- Added a Murph-guided sandbox buyer campaign test planning flow that checks storefront visibility, sandbox advertiser readiness, and the buyer-infrastructure steps Murph would run once server-issued approval tokens are available.
- Added buyer-level outcome and ask rollups to Murph seller analytics.
- Improved Murph document processing so uploaded files can be converted into structured facts, gaps, recommendations, next steps, and brand.json mapping candidates during offline processing.
- Added attributed booking and delivery outcome summaries to Murph seller analytics.
- Added an optional seller analytics panel to Murph responses so storefront operators can visualize recent pricing, composition, and refine activity.
- Improved storefront product composition guidance for price objections, packaging changes, and buyer-history negotiation context.
- Added storefront outcome attribution so seller analytics can connect product exposure to media-buy booking and delivery events.
- Add card-by-card authoring UI for image_carousel creatives. The creative detail page now switches to a carousel editor when the format spec declares a repeatable_group asset slot, letting buyers add, edit, reorder, and delete cards with image uploads and text fields.
- Fixed a bug where deleting a sales agent did not remove it from
service_token.active_adcp_agent_ids. The cleanup query was using the numeric database id instead of the stableagent_idstring, so deleted agents could remain referenced in service-token active agent arrays. - Improved Murph document uploads by summarizing PDF contents, highlighting gaps and recommendations, separating next steps, and recording first-pass processing status for the storefront state rail.
- Added a Murph-operated sandbox test execution path for connected external sales-agent inventory sources.
- Added Murph guidance for planning a test campaign against a connected external sales agent before running any campaign execution steps.
- Improved Murph’s storefront setup flow for registering and assessing external sales agent inventory sources.
- Added per-inventory-source diagnostics to storefront readiness and surfaced them in Murph’s setup rail.
- Returned a clear client error when ADCP webhooks use an unsupported payload envelope.
2.124.0 — May 30, 2026 at 3:54 PM UTC
- Murph seller analytics now includes attributed booking and delivery outcome summaries. The
sellerAnalyticspayload adds a top-leveloutcomesobject and per-runoutcomedetails using last-touch product-overlap attribution. - Murph seller analytics now includes buyer-level outcome and ask rollups, and booked budget is counted once per attributed media buy instead of being inferred from the latest event.
- Murph now surfaces storefront health blockers, including managed sales agent setup tasks, when operators start a storefront conversation.
- Added storefront composition pricing settings for value-based pricing facts, fallback auction pricing targets, Murph-authored structured pricing rules, composed-product pricing options, wholesale product pass-through, and negotiation analytics capture.
- Fixed operator domain setup incorrectly failing with “Domain is already registered to another organization.” Multiple organizations can now share the same operator domain. Setting a shared domain no longer reassigns another organization’s signup routing.
- Allowed storefront owners to test product discovery and Murph-run brief evals against their own configuring storefronts before opening them for transactions. Murph now offers candidate test briefs and runs pre-built, imagined, or pasted briefs through the same dry-run storefront eval path, and intelligence-run records include a user-facing explanation of why products were selected, priced, omitted, or rejected.
- Added buyer endpoints to poll and cancel media buy update proposals: GET /api/v2/buyer/update-proposals/:id and DELETE /api/v2/buyer/update-proposals/:id.
- Show all returned storefronts in Browse the Interchange, simplify the section description, require storefronts to pass marketplace review before appearing to buyers, and notify Slack when a storefront is ready for review.
2.123.0 — May 29, 2026 at 8:18 PM UTC
- Data Delivery is now discoverable from the buyer MCP. Added a Data Delivery section to the buyer skill documentation (concept model, field reference, Probe lifecycle, advertiser-vs-campaign scoping) so
ask_about_capabilitycan surface it, and registered arevalidate_data_delivery_credentialoperation that re-runs the destination Probe without resubmitting the credential. Also published a buyer guide for end-to-end setup across GCS, S3, and Azure Blob destinations. - Added storefront API support for managed-sales-agent buyer advertiser routing, including GAM advertiser search, advertiser ensure, buyer mapping management, recent buyer visibility, and readiness checks for upstream Sales Agent setup blockers.
- Advertisers now have a primary currency. Campaign budget currency defaults to the advertiser’s primary currency when not specified. Selected product pricing is rejected when it uses a currency that does not match the campaign budget currency.
- Aligned Storefront setup, inventory-source, and Merchandising Agent terminology across the v2 API descriptions, docs, and UI copy.
- When a media buy update requires seller approval (
requires_approvalmode), the campaign update endpoint now returns HTTP 202 with aproposalsarray instead of a blocking error. Each proposal entry includesproposalId,mediaBuyId, andstatus: PENDING_SELLER_APPROVAL. Updates that requirerequires_proposalmode continue to return an error until that flow is implemented. - Clarified storefront readiness checks by separating required go-live checks from setup guidance and optional status checks.
- Closed multiple cross-tenant authorization gaps in the
/toolsroute-handler surface (also reached via Murphinvoke_action): customer_getandcustomer_get_seats: now reject requests for customers the caller is not authorized to view (matches existing MCP tool behavior).customer_invitation_approve/resend/reject/cancel: now verify the invitation belongs to a customer the caller can access before forwarding to the internal backend.product_save/product_discover: now scope writes and reads to the caller’s customer for non-SuperAdmin callers; non-SuperAdmins can no longer pollute or read another customer’s product catalog or create generic (null-customer) Scope3 products.seat_details_get: cross-tenant seat fetches by non-SuperAdmin callers now return a not-found error instead of leaking seat name, members, and connected agents.- PSA storefronts now return their warmed catalog products when buyers call
get_products, instead of blocking with acomposition_pendingerror due to missing operating instructions. - Fixed media buy delivery webhooks failing with
VALIDATION_ERRORon thestatusfield since the SDK 8.0.0 upgrade. The delivery notification the SDK passes to handlers contains only the inner report data, not the task-envelopestatusfield thatGetMediaBuyDeliveryResponseSchemanow requires. The fix mergesstatusfrom the webhook metadata before schema validation so sender payloads in the correct MCP format are accepted again. - Non-admin users whose organization has an unaccepted Terms of Service now see a blocking modal with a “Notify your admins” button, instead of landing on a page where all API calls fail silently. If no admins exist on the account, the modal directs the user to support@scope3.com.
- When a media buy update is blocked because the sales agent requires seller approval (rather than a self-serve flow), the API now returns a distinct
SELLER_APPROVAL_REQUIREDerror code instead of the genericCAPABILITY_NOT_SUPPORTED. The error message and recovery suggestions tell the buyer to have the seller approve or activate the buy before retrying. - Surface Sales Agent cached product pricing guidance, forecast freshness, bookability, and managed sync-health drill-down in storefront discovery.
2.122.0 — May 28, 2026 at 1:56 PM UTC
- Added a storefront managed-sales-agent connection test action and secure credential-form deep links so publishers can re-check ad-server connectivity after setup or credential updates.
- Murph chat now supports dragging and dropping PDFs, images, and common document formats into the conversation.
- Added secure Slack handoff buttons for Murph ad-server credential setup so operators can enter SpringServe and FreeWheel credentials in Storefront instead of chat.
- Added
POST /campaigns/:campaignId/creatives/validatefor dry-run creative manifest validation. Calls the ADCP agent’svalidate_inputtool and returns per-target results indicating pass, fail with slot-level violations, or unvalidatable (for nondeterministic formats). - Allow shipping the same Data Delivery type (e.g., IMPRESSIONS) to multiple credentials on a single advertiser or campaign scope. The uniqueness rule on Data Delivery Output arrays is now
(dataDeliveryType, credentialName)instead ofdataDeliveryTypealone — list one Output per destination to fan a type out to several buckets or warehouses. - Fixed signup notifications failing to reach admins when a customer has no domain mapping configured. The system now automatically populates the customer domain and mapping table after the first signup for that customer, so subsequent signups resolve admins correctly without manual intervention.
image_carouselmanifest validation now enforces theallowed_card_media_asset_typesconstraint declared in the format specification. Submitting a card with a disallowed media type (e.g. a video card in an image-only carousel) now returns acard_media_type_invalidvalidation error instead of silently accepting the manifest.- Murph can now read transcript text from supported Loom links and clearly reports when a Loom recording has no readable transcript available.
- Fixed Data Delivery transfers failing with “Anonymous caller does not have storage.objects.list access” by aligning the worker’s
google-auth-libraryversion with the one bundled inside@google-cloud/storage. Impersonated credentials now attach correctly to the export-bucket read, so GCS, S3, and Azure deliveries can complete. - Prevented Murph from confirming reports, learnings, or business profile writes unless the corresponding action completed, and corrected report confirmations to use the ticket ID returned by the filing action.
- Prevented Murph from self-disclosing as an underlying model or treating routine action confirmations as roleplay tests during active conversations.
- Improved Murph storefront setup guidance so next-step questions continue the setup flow instead of reworking agent personality suggestions.
- Kept Murph’s storefront setup tools available throughout storefront setup conversations so operators can activate confirmed product-rule versions from chat.
- Fixed re-inviting users who were previously removed: admins can now successfully re-add users who had been removed from a customer or seat.
- Fixed signup blocking new domains: the CSP backend returns
showPsaBoxbut the agentic API was readingshowTosBox, causing all first-time signups from unregistered domains to be incorrectly blocked. - Fixed brand name drift between
POST /storefront/resolve-brandand the cachedstorefront.brand_namecolumn. The endpoint now persists the resolved brand name and logo URL back to the caller’s storefront row when the resolved domain matches their operator domain, so the Configuration view and the storefront state drawer no longer disagree. The drawer also falls back to the live resolution when the column is null. Also pointed the storefront gear icon at the Account tab instead of Configuration. getFormatDetailsnow discovers AdCP v2 canonical formats (image_carousel,sponsored_placement,responsive_creative,agent_placement) via static SDK definitions, and supplements format discovery withget_adcp_capabilities → creative.supported_formatsfor seller-declared formats.url_typevalues in URL assets now normalize to lowercase (clickthrough,tracker_pixel,tracker_script,vast) to match the AdCP spec. Uppercase inputs are still accepted and automatically lowercased.- Improved managed sales agent sync status reporting so storefronts show derived refresh health, safe warnings, and retry progress instead of raw sync-run failures.
- Renamed the storefront’s per-pass observability endpoints from
/chef-runsto/intelligence-runs. The endpoints now sit under a “Storefront intelligence” framing that scales to future input → reasoning → output use cases beyond product composition (creative approval, media-buy approval, pricing, policy). GET /v2/storefront/chef-runs→GET /v2/storefront/intelligence-runsGET /v2/storefront/chef-runs/:id→GET /v2/storefront/intelligence-runs/:idPUT /v2/storefront/chef-runs/:id/label→PUT /v2/storefront/intelligence-runs/:id/label- The wire field
ingredientsSnapshoton each row is renamed toinventorySnapshotfor consistency with the storefront’s “inventory sources” vocabulary. The OpenAPI schemasChefRun*/LabelChefRunBodyare renamed toIntelligenceRun*/LabelIntelligenceRunBody. - The readiness check id surfaced via
GET /v2/storefront/readinesschanges fromfirst_chef_runtofirst_intelligence_run. - Simplified the S3 Data Delivery Credential shape. The
config.authblock (withmode: ASSUME_ROLE,roleArn, andexternalId) has been removed — S3 credentials now require onlybucketandregion. Scope3 writes objects into the buyer’s S3 bucket using a single shared IAM principal; grants3:PutObject(ands3:DeleteObjectfor the Probe sweep) to that principal in your bucket policy under the Output path prefix. - Carousel card validation now rejects
ctavalues not in the format’s declaredcta_valueslist, returning a structuredcard_cta_invaliderror with the allowed values. Whencta_valuesis not declared, any CTA is accepted.
2.121.0 — May 27, 2026 at 1:18 PM UTC
- Added Data Delivery query support for impressions, clicks, MMP postbacks, and media-buy delivery report types. Outputs configured with these
dataDeliveryTypevalues now produce log-level exports against the corresponding signals tables. TheMEASUREMENTdata delivery type has been removed from the API — it was never wired and is not on the near-term roadmap; submitting it on an Output now returns a validation error. - Add carousel authoring support: POST /campaigns/:id/creatives/create and the buyer MCP api_call tool now accept a cards array for image_carousel format creatives. Each card supports filename (for multipart file uploads) or url (for pre-hosted assets), plus optional headline, description, cta, and landing_page_url.
2.120.0 — May 27, 2026 at 3:23 AM UTC
- Storefronts now appear in buyer-side product discovery as first-class ADCP agents. Every storefront has a matching row in the ADCP agent registry so buyers can reach the storefront’s curated product surface through the same discovery flow they already use for third-party agents. Existing storefronts are backfilled automatically.
- Pre-flight capability guard on campaign update now consumes the structured
available_actions[]vocabulary from AdCP RFC #4480 (PR #4514), with fallback to the legacyvalid_actions[]for sellers that pre-date the spec. Direction-of-change for budget and flight mutations is resolved per-buy (extend vs shorten, increase vs decrease), so mismatches surface before any downstream call. The runtime path additionally parses the structuredACTION_NOT_ALLOWEDerror so failure responses carry the typedattempted_action,reason, andcurrently_available_actionsfields.
2.119.0 — May 26, 2026 at 9:47 PM UTC
- Added Azure Blob Storage as a Data Delivery destination. Buyers can now register a Data Delivery Credential with a container-scoped SAS token and a Data Delivery Output pointing at it; scheduled deliveries write JSONL files into the buyer’s Azure container. The SAS expiry (
se=claim) is parsed at credential submission and surfaced on the credential response asexpiresAtso the credential can be rotated ahead of time. - Creative manifests now accept carousel/multi-card creatives. The
image_carouselcanonical format is fully supported: thecardsasset slot accepts an array of card objects (each with a requiredmediaimage or video, plus optionalheadline,description,cta, andlanding_page_url). Cardinality bounds from the format declaration are validated (min/max card count). Previously, repeatable-group slots were silently dropped during validation. - Bump @adcp/sdk to 8.1.0-beta.13 and wire the beta.13 get_products cache_scope behavior through storefront MCP responses.
- Account-scoped composed products are partitioned from public products across brief and refine flows, and async ADCP response errors are surfaced as advisory errors without making synchronous seller errors non-fatal.
- Added
channelsfield to buyer storefront list and detail responses, surfacing the ad channels each storefront supports (e.g. CTV, display, audio).POST /api/v2/storefront/resolve-brandnow prefers iconographic logo variants (icon, mark, square) over wordmarks when selectinglogoUrl, so storefront cards render a brand mark next to the brand name instead of duplicating it as a wordmark image. - Fixed
apply_proposalfailing with “No discovery results cached” after Redis cache expiry. Proposals are now persisted to the database when discovered so they can be recovered even after the cache expires and ADCP re-discovery fails. - Fixed campaign budget-mode pacing allocating incorrect package budgets when media buys were executed from separate discovery sessions. Each media buy’s packages now receive the correct proportional share of its own product budget across periods.
- Fixed advertiser update so a single PUT can replace Data Delivery Credentials and Outputs together when the new Outputs point at new credentials. Previously, the request was rejected because the old credentials were archived before the Outputs that referenced them were cleared. Updates now upsert credentials first, replace Outputs, then archive credentials no longer referenced.
- Duplicating a creative now generates fresh tracking URLs for the new creative, so the click-through and impression tracker URLs are present immediately after duplication.
- Fixed a crash when setting per-buy pacing periods on campaigns where the media buy start_time is stored as a text string rather than a Date object.
- Fixed platform-managed (PSA) storefronts not appearing in buyer storefront listings. Storefronts backed by Scope3-managed sales agents were invisible to buyers due to a query that required an agent ID - PSA sources have no agent ID by design. These storefronts now appear as connected with no credentials required.
- Fixed storefront not appearing in buyer discovery after going live. When a storefront was set to transacting, any inventory sources whose agents were still pending at registration time would remain stuck in a pending state and be excluded from buyer listings.
- Fixed a validation error when syncing HTML and text creatives to sales agents. Assets are now stamped with the required
asset_typediscriminator field before being submitted to the ADCP protocol. - Accounts that inherit their organization’s contract no longer have their own row, no longer prompt for ToS, and contract reads transparently walk to the organization. New
/api/v2/contractresponse fields (inheritedFromOrganization,organizationId,organizationName) and new status values (inherited_active,inherited_hidden,organization_contract_missing). NewPATCH /api/v2/contractlets organization admins toggle whether inheriting accounts can see contract details and rate cards.POST /api/v2/accept-tosreturns 403 for accounts that inherit. - The
.well-knowndiscovery endpoints (/.well-known/jwks.json,/.well-known/brand.json,/.well-known/oauth-authorization-server,/.well-known/oauth-protected-resource,/.well-known/openid-configuration) now return the same response on bothhttps://interchange.ioandhttps://api.interchange.io. Programmatic API and MCP endpoints remain athttps://api.interchange.io.
2.117.0 — May 25, 2026 at 5:06 PM UTC
- Added per-storefront buyer instructions: notes + discount rules scoped by (operator_domain, brand_domain) and optionally filtered by country. Storefront operators manage rows via
GET/POST/PATCH/DELETE /v2/storefront/buyer-instructions; the product-composition agent resolves matching rows atget_productstime (most-specific notes ordered first, MAX discount across matches). - Approving a pending media buy now forwards the stored request to the underlying source(s) and records the routing so subsequent
update_media_buy/get_media_buy_deliverycalls work end-to-end. When an operator decidesapprovedonPOST /api/v2/storefront/media-buy-approvals/{mediaBuyId}/decide, the service replays the buyer’s create_media_buy payload, fans it out per source, persists the upstream media_buy_ids, and stampsforwardedAt. The response now includes per-source forward results so the operator UI can render partial failures. The decision itself is recorded regardless of forwarding outcome — partial or failed forwards are retryable separately. Direct-forward (offersCampaignApproval=false) and post-approval modes share a singleforwardMediaBuyToSourceshelper. - The product-composition agent now owns pricing arithmetic deterministically: each composed product’s baseCpm, operator discount, and finalCpm are computed server-side from the selected bundles and signals plus any matched buyer instructions. Prompts to the model carry a precomputed price playbook and explicit guidance to vary channel mix and record any excluded bundles in the run rationale.
- Storefront agent hardening from review feedback: scope every storefront media-buy route to the buyer that opened it (cross-buyer leak fix on
get_media_buysand friends), bind each per-storefront MCP session to its authenticating customer (refuse 403 on hijacked session ids), only stampforwarded_atafter every source completes (adds aPOST /api/v2/storefront/media-buy-approvals/:mediaBuyId/retry-forwardfor the operator UI), and stamp a deterministicidempotency_keyon each forwarded source call so retries dedupe upstream. Tightens chef pricing (clamp final CPM at zero, take the min CPM across multi-priced bundles, warn on dropped currency-mismatched signal addons) and trims a few storefront wire shapes (creative-review response is camelCase end-to-end,get_adcp_capabilitiestucks the scope3 storefront block underextensions.scope3, list endpoints drop the fake pagination envelope when the service doesn’t paginate yet). - PSA-backed storefronts now honor operator-stored workflow flags for
offersCreativeReviewandoffersCampaignApproval. Previously all three capability flags were force-locked on for any storefront with a PSA inventory source — operators could not opt their PSA storefront into pass-through review or pass-through approval even when that was what they wanted.offersProductCompositionremains locked on (a PSA must surface composed products or it has nothing to sell), but the review and approval workflow flags now flow fromstorefront_config.settings.capabilitiesverbatim so operators can configure either queue-mode or pass-through per storefront. - Adopted the AdCP SDK’s typed response builders across the storefront MCP surface:
productsResponse,mediaBuyResponse,updateMediaBuyResponse,getMediaBuysResponse,deliveryResponse,syncAccountsResponse,syncCreativesResponse, andtaskToolResponse. Replaces hand-rolledstructuredContentobjects with builders whosedataparameter is the canonical AdCP type — TypeScript now catches schema drift at compile time instead of at storyboard runtime. As a side effect,sync_accountsnow returns properSyncAccountsSuccess.accounts[]entries withbrand,operator,action, andstatus;create_media_buydirect-forward returns a properCreateMediaBuySuccesswithmedia_buy_idandpackages;get_media_buy_deliveryreturns the canonicalGetMediaBuyDeliveryResponsewithreporting_period,aggregated_totals, andmedia_buy_deliveries. Storyboard runner moves from 22-passing/18-failing to 25-passing/16-failing. - Storefront operators can now inspect the product-composition agent’s reasoning over time. Each
get_productspass writes an internal compose-run record capturing the buyer scope it resolved against, the prompt it built, the raw and parsed LLM output, the matched buyer-instructions rows, and the products it persisted. Operators read these viaGET /v2/storefront/chef-runsandGET /v2/storefront/chef-runs/:id; evaluators attach structured labels viaPUT /v2/storefront/chef-runs/:id/label. - Added per-storefront creative review endpoints. When a storefront takes over creative review from the underlying salesagent, buyer-submitted creatives land in a review queue that operators can browse and decide via
GET /api/v2/storefront/creative-reviews,GET /api/v2/storefront/creative-reviews/:creativeId, andPOST /api/v2/storefront/creative-reviews/:creativeId/decide. The decide endpoint acceptsapprovedorrejected. Submissions are idempotent on(creative_id, buyer_customer_id)— a buyer resubmitting the same creative updates the stored payload without resetting a prior operator decision. - Storefront
get_productsnow honors AdCPbuying_modeand therefine[]change-request array.buying_mode: 'brief'is the existing fresh-discovery path;buying_mode: 'refine'lets a buyer iterate on a previous response — entries withscope: 'product'reference an existingproduct_idand an action (include/omit/more_like_this, optionally with anask),scope: 'request'adds whole-response asks, andscope: 'proposal'is acknowledged but not yet honored. Product identity is preserved across refines:more_like_thisandaskmodifications keep the existingproduct_idand update the recipe in place;omitdrops the product from the response;includewith noaskis a verbatim passthrough. The response includes a position-matchedrefinement_appliedarray.buying_mode: 'wholesale'returnsUNSUPPORTED_FEATURE— storefronts are curated discovery surfaces, not raw catalogs. - Storefronts now expose a per-storefront AdCP MCP endpoint at
/storefront/:platformId/mcp. The tool surface is capability-filtered- from the storefront’s flags:
get_adcp_capabilitiesis always available; get_products,sync_creatives, andcreate_media_buyare registered- only when the matching storefront capability is enabled. Pass-through
- storefronts (
advertiseAsAgent === false) and unknown platform IDs - return 404. The endpoint accepts scope3 customer API key auth this
- round; product composition, creative review, and campaign approval
- handlers remain placeholders while their pipelines land.
- Storefront MCP surface (
/storefront/:platformId/mcp) now exposes the full AdCP buyer tool set, not justget_products. New tools:sync_accounts,sync_creatives,create_media_buy,update_media_buy,get_media_buys,get_media_buy_delivery. Capability flags drive the implementation path, not whether a tool is exposed:offersCreativeReviewandoffersCampaignApprovalswitch between operator-managed queues and direct pass-through to the underlying sources.create_media_buyresolves each package’s source from the composed product’s stored implementation_config and fans out per source. Subsequent calls toupdate_media_buy,get_media_buys, andget_media_buy_deliveryread a newstorefront_media_buy_routestable so they route per source automatically.sync_accountsregisters buyers on every connected source and records the per-source upstream account id instorefront_account_routes. - Added per-storefront media-buy approval queue endpoints. When a storefront opts into operator review of buyer-submitted media buys, buyer
create_media_buycalls land in a pending queue and operators decide via the new REST surface:GET /api/v2/storefront/media-buy-approvals(defaults to pending;?status=approved|rejected|revokedto filter),GET /api/v2/storefront/media-buy-approvals/:mediaBuyId(single entry), andPOST /api/v2/storefront/media-buy-approvals/:mediaBuyId/decidewith body{ status: 'approved' | 'rejected', reviewerNotes? }. Decisions are recorded with the reviewing operator and timestamp; double-decide attempts are rejected. Re-submitting the same media_buy_id while pending is idempotent; re-submitting after a decision requires a fresh id. - Added per-storefront operating instructions endpoints. Operators can author versioned markdown rules that the storefront’s composition agent consumes when producing products:
GET /api/v2/storefront/operating-instructions,GET /api/v2/storefront/operating-instructions/active,GET /api/v2/storefront/operating-instructions/:version,POST /api/v2/storefront/operating-instructions(creates a new version, never overwrites prior versions), andPOST /api/v2/storefront/operating-instructions/:version/activate(swaps the storefront’s active version). Versions are immutable and per-storefront monotone — creating a new version produces a clean cutover so composition output for the new rules is distinguishable from the prior generation. - Storefront
get_productsresponses now meet the AdCP v3 schema contract. Every product carriespublisher_properties(derived from the storefront’s platformId),reporting_capabilities(daily UTC reporting with the standard impressions+spend metrics anddate_range_support), and pricing options now use the canonicalpricing_option_id+fixed_priceshape (not the previousrate/is_fixedpair). The response envelope itself includes the v3 canonicalstatusfield and echoes the buyer’s requestcontextback unchanged.get_adcp_capabilitiesaccepts and echoescontextas well. These changes move the AdCP storyboard runner from 3-passing/33-failing to 22-passing/18-failing on the same agent surface — the remaining failures are protocol-level error-code conformance (PRODUCT_NOT_FOUND, VERSION_UNSUPPORTED, TERMS_REJECTED, etc.) and response-shape work on sync_accounts / sync_creatives / create_media_buy envelopes. - Storefront MCP tools now echo the AdCP
contextfield on every response (success and error), reject unsupportedadcp_major_versionvalues with the canonicalVERSION_UNSUPPORTEDenvelope, and validatestart_time/end_timesemantics oncreate_media_buybefore forwarding (reversed dates and past start times returnINVALID_REQUESTdirectly). Every tool’s inputSchema now declarescontext+adcp_major_versionso MCP doesn’t strip them from incoming args. Fixed a column-name bug in the storefront-source resolver (source_kind→execution_type) that was hiding the inventory sources from sync_creatives + sync_accounts fan-out. Storyboard runner moves from 25-passing/16-failing to 34-passing/8-failing on the same agent surface — schema conformance is now table stakes; the remaining failures cluster around behavioral seller errors (TERMS_REJECTED, accept-buy returns media_buy_id) and a single security_baseline assertion. - Simplified
sync_accountson the storefront MCP surface. For embedded storefronts the storefront is the buyer agent, so the call now echoes the submittedaccount_refs back as acknowledged rather than fanning out to underlying sources. Advertiser provisioning on the source side is deferred tocreate_media_buyand owned by each source’supstream_advertiser_modeconfig — the storefront does not remember per-source upstream account ids. Thestorefront_account_routestable was dropped (it was never referenced by approved code paths).storefront_media_buy_routes(the routing forupdate_media_buy/get_media_buys/get_media_buy_delivery) is unchanged.
2.116.0 — May 22, 2026 at 8:19 PM UTC
- Creative manifest list now includes
target_format_ids— additional format IDs a creative covers beyond its primary format. The campaign creative assets page shows which formats are already covered (alongside which are still missing) and allows assigning an existing creative to a missing format without re-uploading assets. - Fixed
apply_proposalreturning “No discovery results cached” when the discovery cache had expired. It now automatically re-runs discovery to repopulate the cache before retrying, matching the existing recovery behavior in other discovery operations. Also extended the discovery cache TTL from 30 minutes to 4 hours. - Fix format selector missing format IDs (e.g. banner_728x90) that are declared on products but not returned by the ADCP creative agent’s listFormats call.
2.115.0 — May 22, 2026 at 11:51 AM UTC
- Child customers can now view their contract from Account Settings → Contract,
- Billing & Invoices. Rate cards inherited from a parent customer are surfaced
- under an “Inherited rate cards” label — when the parent has opted to share
- them the rates appear, otherwise the section indicates that rates are
- inherited from the parent.
- Fixed a race condition where simultaneous storefront inventory source auto-activations (e.g. a source creation and an agent-activation hook firing at the same time) could fire duplicate activation events. The auto-activation UPDATE is now idempotent and only emits a log/audit event for the writer that actually transitions the row from PENDING to ACTIVE.
- Fixed a bug where package budget, pacing, and bid_price updates were not sent to the SSP when updating an active media buy. The SSP would receive the existing values instead of the requested changes, leaving the media buy stuck in PENDING_APPROVAL. Also added Sentry capture for ADCP sync failures that were previously only logged to GCP.
- Fixed inventory sources backed by OAUTH sales agents being auto-activated before the OAuth token exchange completed. Sources now stay PENDING until the agent has a stored credential reference; only NO_AUTH sources skip that check.
- Fixed a bug where verifying one storefront’s operator domain would incorrectly mark all of the customer’s other storefronts as verified. The auto-verification backfill is now scoped to the specific storefront whose domain was just verified, so storefronts with different operator domains remain unverified until each is independently checked.
- Fixed a server-side request forgery vector in the storefront discover-agents flow. The server-side fetch of
https://{domain}/.well-known/adagents.jsonno longer follows redirects, so a third-party host cannot bounce the request to an internal address and have the response surfaced through the discover-agents response. - Fixed
POST /api/v2/storefront/resolve-brandandGET /api/v2/storefront/discover-agentsto return the standard response envelope ({ data, error }) on both success and failure. Previously these endpoints returned raw bodies on validation errors, breaking clients that rely on the consistent wire format used everywhere else in the v2 API. - Hardened Stripe Connect onboarding callback tokens by binding each token to the specific Stripe account and adding a 15-minute expiry. Leaked or replayed callback URLs can no longer be used to mark onboarding complete or mint fresh onboarding redirects.
2.114.0 — May 21, 2026 at 8:00 PM UTC
- Added duplicate creative endpoint. POST /campaigns/:campaignId/creatives/:creativeId/duplicate creates a copy of an existing creative manifest (including all assets) with a “Copy of” prefix on the name.
- Add domain auto-join setting for customer orgs. Admins can enable allowDomainAutoJoin on their customer to let users with a matching verified domain email join immediately as members without requiring admin approval.
- Added S3 as a supported Data Delivery destination. Data Delivery Credentials and Outputs can now target a buyer-owned S3 bucket, with cross-account access via AWS STS AssumeRole. Buyers create an IAM role that trusts the Scope3 AWS principal (with an optional
externalId) and reference it incredential.config.auth.roleArn. Probe validation and per-cadence object delivery use the assumed role; no long-lived AWS access keys are stored. - Operator note: the Temporal worker pod must provide a base AWS identity that the SDK’s default credential provider chain can read, so that
STS AssumeRolecalls can be made. Supported options: (a) GKE Workload Identity Federation → AWS via OIDC (AssumeRoleWithWebIdentity); (b)AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYenv vars for a Scope3 IAM principal withsts:AssumeRolepermission; (c) IAM Roles Anywhere. The buyer IAM role’s trust policy must trust whichever principal we use. Without one of these, the first delivery will fail withCredentialsProviderError. GET /api/v2/accounts/currentnow includescustomerDomainso callers can tell whether the current customer has a registered organization domain (required before enabling domain auto-join).- Fixed inventory source status badges and Activate/Disable actions always showing the wrong state. The UI was comparing lowercase status strings against the API’s uppercase values (
PENDING,ACTIVE,DISABLED), causing health indicators to always appear as “Pending” and status-toggle requests to be rejected by the server. - Fixed CORS rejection for requests from the
https://interchange.ioapex domain to the PSA storefront proxy endpoints. The previous allowlist regex required at least one subdomain, causing fetch requests from the PSA admin iframe to be blocked in production. - Fixed a gap where toggling
transacting: trueon a storefront could bypass the readiness check if the request went through the MCP storefront tool surface or any other internal caller that did not pre-check readiness. The gate now runs insideStorefrontService.update()itself, so every path returns the same blocker list when required setup is incomplete. - Murph conversations are now persisted and retrievable. Added two member-scoped endpoints —
GET /v2/murph/conversationsandGET /v2/murph/conversations/:conversationUid— and a shareable/$customerId/murph/c/:conversationUidroute in the UI so the chat history survives page refresh and can be linked to a teammate. - Add Murph proactive surfaces: a digest endpoint that summarizes unread notifications, personalized starter prompts driven by user state, an online/health indicator, and a closed-set
?askMurph=<intent>&entity=<entityRef>deep-link convention with “Ask Murph about this” buttons on campaign, advertiser, and sales-agent detail pages. The digest is automatically folded into the orchestrator’s first-turn context so Murph can answer “what changed?” without an extra round-trip. - Storefronts now carry a
capabilitiesblock on the v2 response declaring which AdCP extensions the storefront advertises to buyers:offersCreativeReview,offersCampaignApproval,offersProductComposition. A derivedadvertiseAsAgentboolean tells callers whether the storefront should be addressed as an AdCP agent (vs. pass-through to the underlying inventory source). Embedded (PSA-backed) storefronts have all three capabilities locked on withcapabilitiesLocked: true; third-party storefronts default all off (pass-through). ThePATCH /api/v2/storefrontbody accepts acapabilitiespatch — locked storefronts reject writes that would turn any capability off. - Buyer-facing surfaces now display the storefront’s name as the seller identity instead of the underlying sales agent’s name. The storefront IS the agent buyers see in this product — underlying sales agents (third-party AdCP agents and embedded managed agents) are internal routing detail, not separate seller identities. Product cards, the discovery
productCardmodal, media-buy sections, and proposal badges all read fromstorefrontNamenow. Discovery responses stampstorefrontId/storefrontNameon every Proposal and persist them through cached rails so the seller label is reliable across both fresh discovery and saved discoveries that get replayed. Cached rails group by storefront instead of sales agent — products from multiple underlying agents that belong to the same storefront collapse into one rail.
2.113.0 — May 20, 2026 at 11:19 PM UTC
- Measurement sources now expose an
outcomeTypesarray field listing all record-level outcome type slugs the source produces. This enables correct linkage between multi-metric sources (e.g. video reports delivering impressions, clicks, and video quartile events) and their individual measurement records. - Fixed the Creatives tab being blank when “All advertisers” is selected on the buyer home page. The tab now auto-selects the first available campaign and loads creatives correctly.
- Fixed seat-scoped API tokens being rejected with
ACCESS_DENIED(“No user context available for seat permission check”) when calling endpoints scoped to their assigned advertiser. The token’s seat role was set during authentication but not propagated into the service-layer context used by seat access checks. - Reporting data now persists additional AdCP delivery metrics when sales agents report them: conversion value, ROAS, new-to-brand rate, cost per acquisition, cost per click, reach unit, viewed seconds, attention seconds, attention score, engagements, follows, saves, and profile visits. Package-level breakdowns also persist delivery status, paused state, and is-final flags. Previously these fields were dropped during ingestion; they are now stored alongside existing impression, click, view, and conversion metrics.
- Replace the storefront
statusenum (PENDING / ACTIVE / DISABLED) with two simpler stored fields:transacting(boolean) andarchivedAt(timestamp). The API now returns a derived, read-onlydisplayStatuswith one of three values —configuring,transacting, orarchived— computed from those two fields. Clients toggle live/paused by settingtransacting: true | falseonPUT /storefront; archiving is now a single explicit operation atPOST /api/v2/storefront/archivethat setsarchivedAtand forcestransacting = false. Archived storefronts are read-only — every mutation against an archived storefront is rejected. Existing rows are migrated automatically (status = 'ACTIVE'→transacting = true; everything else →transacting = false).
2.112.0 — May 19, 2026 at 10:42 PM UTC
- Property list file uploads now return 202 Accepted immediately and process identifier resolution in the background. Poll the GET endpoint for status updates. Large uploads no longer risk load balancer timeouts.
- Users who request access to an existing organization now see “Your access request is pending approval” on the signup screen instead of the misleading “An invitation is required” message. We also post a Slack notification listing the org’s admins (and page oncall when there are none) so requests don’t sit unanswered when an org’s only admins are stale or unreachable.
- Grouped the
logEventendpoint under the Event Sources section in the Buyer API reference, alongsidelistEventSourcesandsyncEventSources, so all event-source-related endpoints appear together. - Improved ad-product retrieval on campaigns:
mediaBuys[].products[]onGET /campaigns/:idnow includeproductNameandpublisherNameso callers no longer need to reconstruct names from reporting CSVs or audit logs.GET /campaigns/:id/productsis now the authoritative list of every ad product attached to a campaign. It sources from the campaign’s media buys (joined with the local products cache) and folds in any discovery-staged products not yet executed. Each entry includesproductName,publisherName,salesAgentName, pricing, and the media buys it lives on.GET /campaigns/:id/productsnow accepts amediaBuyIdquery param (single or repeated) to narrow the response to specific buys, avoiding context-window truncation on campaigns with many products.- Property lists now create a local
Propertyrow for every uploaded site domain that didn’t already have one (same shape as the canonical web property creation path:DISPLAY-WEBchannel,AUTO_SYNC,BROWSER). Previously, identifiers without a matching Property fell intounresolvedIdentifiersand were silently dropped from the list, so they didn’t take effect at bid time. Buyer-submitted exclusion and inclusion lists now honor the full domain set. - Reframed the Add inventory source chooser around what storefront operators actually know about their setup. Two side-by-side cards — “I don’t have a sales agent” (Managed) and “I have my own sales agent” (BYO/AdCP) — replace the title-cased “Connect an ad server / Connect an agent / Link a storefront” rows. Federation moves into a quiet “Coming soon” rail below the cards so it stops competing for attention before it ships. Downstream forms are unchanged.
2.111.0 — May 19, 2026 at 2:40 PM UTC
- Added
POST /api/v2/identity-match/targeting, returning the seller-keyed audience targeting configuration for every package available to the authenticated token. System tokens receive every active package; customer tokens receive packages they own as a buyer or host as a seller. An optionalafterISO-8601 cursor switches the response to delta mode, returning only configs whose package or owning media-buy was updated/archived since that instant.targetSegmentsis audience-only —audience_includemaps toanyOf,audience_excludetononeOf. - Allow attaching a clickthrough URL alongside uploaded creative assets on every format. Previously the Clickthrough URL field was hidden (and the slot rejected by the API) when the resolved format spec didn’t declare a
click_url/clickthrough_url/landing_pageslot, forcing buyers to choose between files OR a click URL. The slot is now accepted universally and stored on the manifest; formats that declare it continue to render it in the AdCP payload. - The ADCP property list resolve endpoint (
GET /lists/{listId}) now supports pagination viamax_resultsandcursorquery parameters and returns apaginationobject withhas_more,cursor, and (on the first page)total_count. Defaults to 1000 identifiers per page; max 5000. - Storefront demand contact now enforces a both-or-neither rule: name and email must be set together or both cleared. The operator UI has an explicit “Remove contact” action, and partial updates that would leave the pair half-set are rejected with a validation error.
2.110.0 — May 19, 2026 at 3:31 AM UTC
- Added a demand-contact name and email to the storefront configuration. Operators can curate the person who fields buyer demand signals (RFPs, prospective briefs, weekly digests); the fields are surfaced via
GET /api/v2/storefrontasdemandContactNameanddemandContactEmail, and can be edited any time throughPUT /api/v2/storefront. Passnullto clear either value. - Fixed two ways a customer’s operator domain could be incorrectly auto-verified:
-
- Parent-fallback ignored the child’s own domain. The CHILD-customer verification fallback was returning
verifiedwhenever the parent customer had any active member matching the parent’s registered domain, regardless of whether the child’s owncustomerDomainmatched the parent’s. As a result, a child customer parented under (e.g.) Scope3 could appearverifiedfor an unrelated operator domain because Scope3 employees matchscope3.com. The fallback now only applies when the child’scustomerDomainequals the parent’scustomerDomain.
- Parent-fallback ignored the child’s own domain. The CHILD-customer verification fallback was returning
-
- Approval rows were keyed only by customer. Each
customer_domain_approvalrow is now bound to the specific domain it was issued for (approved_domaincolumn). Previously the read path returnedverifiedwhenever any approval row existed for a customer, even if the customer had since changedcustomerDomainto a different value than the one originally approved. Legacy rows withoutapproved_domainare no longer trusted; customers who still qualify via an active member’s email re-verify automatically on the next read, otherwise a SuperAdmin must re-attest under the current domain.
- Approval rows were keyed only by customer. Each
2.108.0 — May 18, 2026 at 10:48 PM UTC
- Creatives now support promoting a different asset to “primary” (the renderable source). Pass
primary_asset_idon the update endpoint to demote the current primary and promote the target asset. Only IMAGE, VIDEO, AUDIO, HTML, and VAST assets may be set as primary. - Pre-launch campaigns can now be edited freely. Start date and pacing periods may be modified after the original start date has passed, as long as the campaign has no live media buys (any non-draft, non-archived buy blocks the edit). Pacing periods also accept a budget or weight of
0so a single week can be skipped without removing the period. - Cleaned up the campaign creative assets page: the upload modal no longer auto-opens when a creative has unresolved HTML asset refs (the missing-assets banner now has an inline upload button instead), and the Native copy tab is always visible across both the create-creative flow and the upload-to-existing-creative modal with clear empty states when a format hasn’t been picked or doesn’t declare native slots.
- The single-creative upload paths on the campaign creative assets page (both create-creative and add-files-to-existing) now accept
.ziparchives. Dropped zips are expanded client-side into their constituent files before upload, matching the behavior of the bulk upload modal. Nested zips are extracted recursively, so standard HTML5 ad bundles work in all upload spots. - Embedded managed sales agents now support SpringServe and FreeWheel in addition to Google Ad Manager.
- When connecting an ad server you can pick the adapter type and supply the appropriate credentials:
- Google Ad Manager — Scope3 provisions a per-customer service account; you grant it access in your GAM admin console and supply your numeric network code.
- SpringServe — log-in email + password (the salesagent caches a 2-hour token and refreshes it automatically). An API token is also accepted for testing.
- FreeWheel — Publisher API username + password (auto-refreshing OAuth2 password grant). A 7-day temporary access key is also accepted under the advanced section for testing.
- Publisher-supplied credentials are forwarded to the upstream salesagent tenant at provision time and never persisted by Scope3. Only non-secret display fields (login, environment, default advertiser/demand-partner id) are stored so the UI can render “connected as …” after provisioning. Rotating credentials on a live tenant preserves all tenant state (products, principals, sync history) via the new
PUT /api/v2/storefront/inventory-sources/{sourceId}/adapter-configendpoint. - Fixed the storefront card editor so selecting “North America” no longer renders as “Namibia”. The region group code now uses
NORAM(matching the signals subsystem) to avoid colliding with the ISO 3166-1 alpha-2 country codeNA(Namibia); existing storefronts that storedNAfor the North America group are transparently migrated on read. - Fixed media buy updates being silently dropped by sellers that dedupe on the ADCP idempotency key. The key for
update_media_buypreviously stayed constant across every edit of the same media buy, so a spec-compliant seller would replay the response of the first update for every subsequent one and the new budget/pacing/bid_price/targeting changes never reached the seller’s ad server. The key now incorporates a fingerprint of the request body, so distinct edits get distinct keys while retries of the same edit still de-duplicate as intended. The same fix is applied to cascade pause/resume and to package-level cancellations. - Storefront now surfaces inventory-sync state from the managed sales agent: an active PSA shows a dedicated “Inventory sync” row in the source detail dialog (with a Retry button when failed), and the setup-tasks checklist shows a blocker task when inventory sync has failed and an informational row while the first sync is running. Closes #2549.
- When a managed sales agent adapter probe fails, the storefront UI now shows a specific next step driven by the upstream’s structured
remediationhint: vendor_enables_role— your account doesn’t have the API role this operation requires; contact your SpringServe / FreeWheel rep to enable it.customer_rebinds_account— re-enter your username (or email) + password.customer_rotates_token— paste a fresh temporary access key or API token.- The full upstream message and any
vendor_faultblock continue to be surfaced as supporting detail so support engineers see exactly what the ad server returned. - Storefront inventory-sync state is now webhook-backed. The salesagent’s
sync_run.completed/sync_run.failedevents land on a new agentic-api receiver (POST /webhooks/psa-sync/:customerId/:tenantId, HMAC-signed) and update a persistedinventorySyncblock on each PSA connection — visible to the UI directly viaPsaConnection.inventorySync. The per-PSA/statuspoll cadence drops from 30s to 5 min as a safety net for missed deliveries; the dialog and setup-tasks panel read the persisted state so they reflect sync changes within seconds. - Set
PSA_WEBHOOK_SECRET(shared HMAC secret) andPSA_WEBHOOK_CALLBACK_BASE_URL(defaults toBASE_URL) to enable the webhook path. When unset, the receiver returns 503 and the polling fallback alone keeps the state fresh. Closes the V2 of #2549. - The Connect Ad Server dialog now shows the right copy when GAM rejects a managed-sales-agent setup. Typos point at the network code, propagation delays show the soft “wait a few minutes” affordance, and an invalid service account auto-pages the operator instead of confusing the publisher. The PSA connection’s
lastErrorCodecarries the new typed values (ADAPTER_NETWORK_NOT_FOUND,ADAPTER_PERMISSION_DENIED,ADAPTER_INVALID_CREDENTIALS,ADAPTER_INVALID_CONFIG,ADAPTER_CONNECTION_FAILED) so external API consumers can branch on the failure class instead of parsing the message.
2.107.0 — May 17, 2026 at 9:26 PM UTC
POST /api/v2/storefront/psais now atomic: it provisions the managed sales agent tenant upstream and writes the local connection row in a single transaction. The connection is either fullyactiveon response or no row is persisted, eliminating the in-betweenpending/failedstates that previously required client-side retry plumbing.- Removed
POST /api/v2/storefront/psa/{psaId}/provisionandPOST /api/v2/storefront/inventory-sources/{sourceId}/provision— they are no longer needed. Retries are clean re-POSTs of the original create request. - Added
POST /api/v2/storefront/psa/{psaId}/reactivateandPOST /api/v2/storefront/inventory-sources/{sourceId}/reactivateto bring a deactivated tenant back online without re-running the create flow. - If the salesagent rejects provision with
EXTERNAL_ORG_ID_CONFLICTand returns the conflicting tenant id, the agentic-api now adopts that tenant into a fresh local row instead of erroring. Self-healing when the local DB lost a row but the upstream tenant survived (and friction-free in local dev when a dev wipes the agentic DB but not the salesagent’s). - Fixed click and impression tracker URLs being generated against
/clkand/imppaths, which return 404 on the tracking endpoint. Tracker URLs now point at/agentic/clkand/agentic/impto match the routes the tracking service exposes. New creatives created after this change will produce working tracker URLs; existing creatives need their tracker URLs backfilled separately.
2.106.0 — May 15, 2026 at 10:57 PM UTC
- Storefront compliance checks are now cached for 30 minutes per agent, so the inventory sources page no longer re-runs the full AAO compliance suite on every load. Each agent tile shows a Retry button next to the health label to force an immediate re-check when you need a fresh answer. Tiles also wait for the compliance result before reporting “Healthy”, which fixes a transient mismatch where a failing agent could briefly read as healthy while the check was still in flight.
- Fixed operator-domain verification status flipping between “Verified” and “Pending verification” depending on who was viewing the storefront. Verification is now decided entirely server-side based on whether any active member of the customer has an email matching the registered domain (no longer restricted to ADMIN role), and the decision is persisted with an audit reason so the chip stays stable across viewers.
- Fixed a flickering “Approve GAM service-account access” row on the storefront inventory-sources setup checklist. The row previously reappeared on every refetch of the managed-sales-agent status feed even when the PSA was already healthy and serving — provisioning success itself proves GAM honored the service account, so the row no longer renders once the connection is active. Later revocations continue to surface via the existing sync-failure row.
- Fixed dynamic HTML5 creative previews showing broken images for Google Web Designer (GWD) banners. The asset-reference rewriter now recognizes the
source=attribute used by<gwd-image>custom elements, and template auto-detection picks the HTML template whenever an HTML wrapper is uploaded alongside sibling images (previously the first image in the upload list won, leaving the creative classified as a static image).
2.105.0 — May 15, 2026 at 7:14 PM UTC
- Creative manifests now accept
text_assetsandurl_assetskeyed by AdCP format slotasset_id, so structured formats like native can carry headline, description, business name, disclosure, and landing page copy without uploading text files. The creative dashboard exposes a Native copy form per format spec. - Added storefront reporting endpoint
GET /api/v2/storefront/reporting/metrics. Returns delivery metrics for every media buy that the storefront’s sales agent(s) are a party to, organized as advertiser → media buy → package. Supportssummaryandtimeseriesviews, date-range filters (startDate/endDate/days), optionalinventorySourceIdfilter,download=truefor CSV export, anddemo=truefor synthetic data. - Storefront Communications: the per-event email/Slack toggle table is now hidden until at least one notification destination (notification email or Slack webhook) has been saved. The table’s toggles cannot fire without a saved destination, so showing it beforehand suggested controls that didn’t yet work.
- Validation errors for enum-like fields (e.g.
geo_metros.system,geo_postal_areas.system, campaign status) now list the accepted values in the error message (“must be one of: nielsen_dma, uk_itl1, …”) instead of returning a generic “Invalid input”. - Storefront Communications: when no notification channel is configured, the page now shows a quiet placeholder card (“Connect a channel above to choose which events trigger a notification.”) in place of the per-event toggle table, matching the design.
- The storefront Team page now lists pending invitations alongside accepted members, with Resend and Cancel actions so admins can manage stuck invites without leaving the workspace.
2.104.2 — May 15, 2026 at 2:14 PM UTC
- Company domain now shows as verified immediately when an admin on the account has an email at that domain — no extra approval step required. Previously, new sellers signing up with their own work email saw “unverified” until they created or edited a storefront, which blocked the “Connect an agent” path.
- Fixed
Forbidden: identity_org_mismatchwhen opening a managed sales agent admin UI for storefronts with multiple sales agents. The proxy now stampsX-Identity-Org-Idwith the exact value the upstream tenant was registered with, instead of the unsuffixed customer id. - When provisioning a managed sales agent fails, the storefront UI now keeps the “Connect an ad server” dialog open and surfaces the actual error inline (previously the dialog closed silently and the publisher was bounced back to an unchanged storefront page with no signal). Provisioning failures against the upstream salesagent also fire a high-priority ops alert to Sentry + Slack so the on-call team is paged immediately instead of waiting for a customer escalation. User-fixable failures (e.g. bad GAM credentials) still surface to the publisher inline but do not page the ops channel.
2.104.1 — May 15, 2026 at 7:38 AM UTC
- Fixed “Connect an ad server” tile in the Add inventory source modal being incorrectly disabled when a storefront already had a managed sales agent. Multiple managed sales agents per storefront are supported, and the tile is now always enabled.
2.104.0 — May 15, 2026 at 2:49 AM UTC
- Campaign
constraintsnow accept AdCP-shaped targeting fields directly:geo_countries,geo_countries_exclude,geo_regions,geo_regions_exclude,geo_metros,geo_metros_exclude,geo_postal_areas,geo_postal_areas_exclude,language,device_type,device_type_exclude, anddevice_platform. When set on a campaign, these flow into every media-buy package’stargeting_overlay— include lists intersect with package targeting, exclude lists union. The legacycountriesfield is accepted as a deprecated alias and normalized togeo_countries. - Storefronts can now add multiple managed sales agents (e.g. one GAM network per brand) instead of being limited to one per customer. The managed-sales-agent REST surface is now id-keyed:
GET /api/v2/storefront/psareturns an array,POST /api/v2/storefront/psacreates a new connection, and per-PSA actions live under/api/v2/storefront/psa/{psaId}/.... Existing managed sales agents continue to work without any data migration. - Customer context selected via
customer_switchnow stays scoped across short breaks. The stored selection slides its expiry forward each time it’s applied, so an actively-used customer scope persists until the user is idle for more than 24 hours. - The storefront card is now operator-curated. The
GET /api/v2/storefrontresponse andPUT /api/v2/storefrontrequest body accept five new fields —membershipStatus(AAO_FOUNDING_MEMBER/AAO_MEMBER/NONE),regions(ISO 3166-1 alpha-2 country codes and group codes likeGLOBAL/EMEA),description,channels(ADCP channel codes), andwebsite— so operators can tune what buyers see on Interchange without re-publishing brand.json. brand.json still seeds identity (name, logo, colors, description, website); these overlays let publishers fill in fields brand.json doesn’t reliably carry.
2.103.0 — May 14, 2026 at 11:20 PM UTC
- Added
DELETE /api/v2/accounts/{customerId}to hard-delete a child customer account. The caller must be an admin on the parent (or a Scope3 SuperAdmin) and cannot delete the customer they are currently scoped into. The endpoint refuses with 409 Conflict if the child still has linked resources, so existing accounts with data continue to require a deactivation flow. - Discovered products are now grouped by storefront instead of by sales agent. Each product carries
storefrontIdandstorefrontNamereflecting the storefront it was discovered through. A single sales agent that backs inventory across multiple storefronts now appears under each storefront’s group with its own slice of inventory, so buyers see inventory the way they configure it — one group per storefront they’ve connected to. - Documented the
POST /advertisers/{advertiserId}/log-eventendpoint in the v2 OpenAPI spec for logging conversion and marketing events (ADCP log_event spec). - Fixed a 404 on the embedded storefront’s “Create product” flow caused by app-level salesagent JSON APIs (e.g.
/api/formats/list?tenant_id=…) not being routed by the storefront proxy. The proxy now also forwards/storefront/psa/api/*to upstream/api/*, resolving the tenant from thetenant_idquery parameter for session validation. This unblocks the format/targeting widget and the downstream 500 onproducts/addthat resulted from posting with empty targeting data. - Fixed an issue where users signing in through enterprise SSO could be silently rejected when the WorkOS access token didn’t carry an exact-match email claim. User lookup by email now falls back to a case-insensitive match so a casing skew between the identity provider and the user record no longer blocks first-time login; subsequent API calls additionally fall back to the WorkOS user id, and the auth middleware logs a warning that names exactly which claims the token did carry, so the failure mode is no longer invisible.
- Fixed an SSO sign-in failure where users with accumulated duplicate auth cookies (for example, a host-only
staging.interchange.iocookie alongside the parent-domain.staging.interchange.iocookie) were silently bounced back to the login page. The browser was sending both cookies on the same request and the server was reading the stale one, so the freshly minted session was unusable. Auth cookie writes now emit clear directives for every historical (domain, path=/) variant before setting the fresh value, so affected users self-heal on their next successful sign-in.
2.102.0 — May 14, 2026 at 2:20 AM UTC
- Reworked the campaign creative assets page: replaced the creative dropdown with a server-paginated list view of all creatives for the campaign (search, multi-select with bulk delete, per-row quick edit and delete) and added a back link from the creative detail view. The list also auto-picks the first advertiser and campaign on landing so you see content immediately instead of empty filters.
- Bulk re-uploading creatives no longer creates duplicates. When a creative manifest with the same name already exists in a campaign, the create endpoint returns the existing manifest with
already_exists: trueinstead of inserting a duplicate. If the request carried files, the response also includesignored_fileswith the count that was dropped (use the update endpoint to add or replace assets on the existing manifest). The bulk upload UI surfaces this as a distinct “Already uploaded” row state with an “N files ignored” hint when applicable, so users can safely re-run a partial upload to finish what was missed. The pre-batch row label changed from “Queued” to “Waiting” to avoid implying a server-side queue. - Fixed a bug where a user invited as admin to a customer they already had a default permission for was silently kept at their lower role. Accepting an invitation now upgrades the existing permission to the invited role (never downgrades).
- Fixed an MCP session bug where switching into another customer would silently revert to the user’s home customer whenever the session was recreated on a different pod. Subsequent writes (e.g. campaign creation) now consistently land in the customer the caller switched into.
- Added a way for admins to invite specific people (vendors, contractors, new teammates) to their customer’s existing Slack or Teams support channel without changing seat membership. Available via the new
POST /api/v2/customer/communication-channel/invite-usersendpoint and the “Invite people to the channel” form in both the admin support-channels section and the storefront Communications settings. Newly invited seat members are now also automatically added to the communication channel when one is provisioned. The communication-channel POST endpoints (set provider, resend invite, invite users) now require anADMINorSUPER_ADMINcustomer role. - MCP clients (Claude Code, Claude Desktop, mcp-remote) can now auto-discover OAuth on the
/mcp/*endpoints. Previously, 401 responses from these endpoints did not advertise the OAuth Protected Resource metadata, so clients without a pre-configured API key had no way to initiate the OAuth flow. They now include a standards-compliantWWW-Authenticate: Bearerchallenge pointing at/.well-known/oauth-protected-resource. POST /api/v2/buyer/campaignsnow rejects withACCESS_DENIEDwhen the request’s customer context does not match the advertiser’s owning customer. Previously, unscoped SuperAdmin sessions could create a campaign tagged to their home customer while pointing at another customer’s advertiser, producing cross-customer data that was invisible to the advertiser’s actual customer.
2.101.0 — May 14, 2026 at 12:20 AM UTC
- Disconnecting an external ADCP agent now keeps the source visible in the inventory list as “Deactivated” (mirroring the managed-sales-agent lifecycle) instead of archiving it. The source detail dialog shows a single “Reconnect” action for a deactivated agent. Reconnecting a
NO_AUTHagent no longer fails with a spurious “Cannot activate agent without authentication configured” validation error. - Extend org-admin-on-parent access to a few remaining surfaces that still required a direct user_permission row on the target customer. The MCP customer_switch tool, the stateless MCP current-customer overlay, and the accept-tos endpoint now all honor admin permission on a parent customer, matching the behavior introduced for service-token creation.
- Fix unsupported MIME types on creative uploads being rejected as ECONNRESET (connection reset) instead of a clean 400 Validation Error.
- Fixed creative file uploads failing with “Unsupported file type: application/octet-stream” when clients (such as Safari or generic HTTP tools) do not set an explicit MIME type. The server now resolves the actual content type from the file extension and returns a proper 400 validation error instead of a 500 when the MIME type cannot be determined.
- PSA provision now returns 503 (instead of 500) when the per-customer service account exists but its Secret Manager key is not yet retrievable. This matches the existing 503 surface for the “SA missing” case and tells the storefront UI to retry rather than showing a generic server error.
- Map upstream salesagent Tenant Management API failures (network errors, 5xx responses, wire-shape drift) to 503 Service Unavailable instead of 500. The storefront UI can now show a “retry” state when the PSA backend is briefly unhealthy instead of a generic server error.
- Added a multipart upload endpoint for property lists (
POST /advertisers/:advertiserId/property-lists/upload) that accepts xlsx or csv files up to 100,000 identifiers per request. Removes the need to batch large exclusion or inclusion lists through repeated JSON calls. - Added a campaign-scoped visibility endpoint (
GET /campaigns/:campaignId/property-lists) and anincludePropertyLists=truequery flag onGET /campaigns/:campaignId. Both return the property lists actually applied to a campaign via its media-buy packages, so callers can verify exclusion / inclusion state at a glance without traversing media buys manually. - Tightened agent guidance on
create_property_listandupdate_property_list: directs the agent to the upload endpoint for large lists, and requires a server-confirmed verification step (list_property_listsafter create,get_property_listafter update) so a write is never reported successful without ground-truth confirmation. - Removed the one-agent-per-storefront limit. Storefronts can now connect as many
AGENTinventory sources as they need;MANAGED_SALES_AGENTrows remain slot-exempt as before. - Storefront homepage now renders real data instead of stubs:
- Inventory source responses include two new optional fields,
reportingTypeandreportingPollingCadence, projected from the underlying agent registration. Use them to show how each agent reports delivery (polling/webhook) and its cadence (hourly,daily, etc.) without a follow-up query. - Storefront setup checklist in the UI now covers operator-domain verification, brand-profile completeness, billing connection, per-source OAuth handshakes, and the GAM service-account grant — each with a deep-linked CTA.
- Source tiles populate the Open work column from
PsaTenantStatusfor managed sales agents, Reporting from the new agent fields, and append the endpoint host and GAM network code as identity chips.
2.100.0 — May 13, 2026 at 6:17 PM UTC
- Adds the Data Delivery Credential entity and the data plane that delivers configured Data Delivery Outputs.
- Credentials: Buyers can now register reusable destination credentials per advertiser via
dataDelivery.credentials[]onPOST/PUT /api/v2/buyer/advertisers. Each credential carries the auth target (e.g., the GCS bucket) and is validated asynchronously by a destination-specific Probe. New and updated credentials are returned withstatus: "PENDING"while the Probe runs; clients should pollGET /api/v2/buyer/advertisers/:id(or call the dedicated revalidate endpoint) to observe terminalVALIDATEDorFAILEDstatus. UsePOST /api/v2/buyer/advertisers/:id/data-delivery-credentials/:name/validateto re-run the Probe after fixing destination-side permissions. - Outputs now reference credentials by name:
dataDelivery.outputs[].deliveryConfigno longer carries thebucketfield. Each Output instead specifiescredentialName(referencing a credential within the same advertiser) and only the per-subscription address (e.g.,pathPrefixfor object stores). The credential’sdestinationTypemust matchdeliveryConfig.type. - Delivery: Configured Outputs now actually ship. A reconciliation workflow materializes Output rows into Temporal schedules, which fire a delivery workflow that exports the data to a staged GCS location and transfers it to the buyer’s destination. Each delivery is recorded in
data_delivery_log. v1 supports GCS only; S3, Azure Blob, Snowflake, and Databricks land additively. - Fix API key creation failing for org admins on child customers. When an admin accessed a child customer via parent-child hierarchy, creating a customer-scoped service token returned “User does not have access to this customer” because the user has no direct UserPermission row on the child. The token is now created as an org-level token in this case, mirroring how SuperAdmin acting on another customer is handled.
- Fixed the Personal API keys page so SuperAdmins impersonating a specific user see only that user’s keys, instead of every personal key at the customer. SuperAdmins scoped to a customer (without user impersonation) keep the admin view that lists all users’ personal keys with the User column.
- PSA provision now returns
503 SERVICE_UNAVAILABLE(instead of400 VALIDATION_ERROR) when the per-customer service account is still being provisioned. The condition is transient — clients should retry — and the new status code reflects that. - Sign-in with Google and SSO now respect the email you type. The login form forwards the typed email as a login hint and asks Google to show its account chooser, so you sign in as the account you typed instead of silently being signed in as whichever Google account your browser already has cached.
- The discovery card modal on
/storefronthas been polished: title is now “Your storefront card” with subtitle “This is how you appear to buyers on Interchange.”, the primary action reads “Edit card” in the brand-primary color, and the floating “Verified” chip has been removed. Card-body typography has been tightened to match the directory rendering. - Fixed
update_media_buyand campaign-update flows incorrectly rejecting updates on media buys with multiple version history rows with “Media buy has no products. Cannot validate creative formats.” Creative format validation now resolves against the live version of the media buy. - Storefronts now get a dedicated GCP service account per customer instead of sharing a single global account. Service accounts are automatically created when a new seller customer is provisioned, with keys stored securely in Google Secret Manager. A SuperAdmin backfill endpoint is available to provision service accounts for existing sellers.
update_campaignacceptspacingPeriodson eachmediaBuys[]entry. Use this to shape spend on one specific media buy (e.g. a heavy-up on a publisher with seasonal or event-driven inventory) without affecting the other media buys under the campaign. The per-buy schedule replaces the campaign-levelpacingPeriodsshape for that buy and uses the samemode+periods[]shape. OnDRAFT/PENDING_APPROVALbuys, the schedule is persisted and used at execute time. OnACTIVE/PAUSEDpaced buys, strict appends are sent to the seller viaupdate_media_buy.new_packages(requires the seller to advertiseadd_packagesinvalid_actions). Bootstrapping pacing onto an unpaced live media buy is rejected, create a new media buy instead. CampaignGETresponses surfacepacingPeriodson each media buy with resolved budgets.- Fixed campaign-level
pacingPeriodscascades inbudgetmode: when appending a new period to a campaign with multiple paced media buys, each period’s budget is now split across the buys proportionally to each buy’s share of total budget. Previously each buy treated the period budget as its own, multiplying total spend by the number of paced buys. - Managed sales agent actions (provision, launch, test connection, refresh, deactivate, status, ad-server config) are now exposed under the unified
/api/v2/storefront/inventory-sources/:sourceId/...surface in addition to the legacy/api/v2/storefront/psa/...routes. New clients should target the inventory-sources path; the legacy/psa/...surface stays for one release while existing UIs migrate. - The managed sales agent now surfaces through
/api/v2/storefront/inventory-sourcesalongside external agents, andexecutionTypevalues move to UPPER_CASE: existing'agent'becomes'AGENT'and the new managed-sales-agent value is'MANAGED_SALES_AGENT'. Inventory-source responses include an embeddedmanagedSablock (provisioning status, tenant id, ad-server config) when the source is managed. - Breaking change: clients reading or writing
executionTypemust use the new UPPER_CASE values. Existing rows are migrated in place (no action required for stored data). The change alignsexecutionTypewith the other UPPER_CASE wire enums on the storefront surface (API_KEY,MCP,SALES, etc.). - Existing
/api/v2/storefront/psa/...endpoints continue to work unchanged; subsequent releases will move actions under the inventory-sources surface. - Disconnecting an inventory source from a storefront now archives the row instead of hard-deleting it, preserving the prior agent binding, original creation time, and audit-trail context. Archived rows are filtered from all list/lookup endpoints, and the same
source_idcan now be reconnected after disconnection. - Breaking: the
statusfield on inventory source responses now returns UPPERCASE values (PENDING,ACTIVE,DISABLED) instead of lowercase. This aligns with every other status field on the API (storefront, agent, media buy). Update any client code that comparedsource.statusagainst lowercase strings. The DB column is also a real Postgres ENUM so dirty values can’t be written through raw SQL. - Storefronts can now federate with each other through “Link a storefront” — a buyer storefront asks a seller storefront to authorize surfacing the seller’s inventory. Once the seller approves, buyer traffic can fan out through the seller’s underlying agents and ad servers. New REST endpoints under
/api/v2/storefront/links(buyer: create / cancel; seller: approve / reject / cancel), plus/api/v2/storefront/storefronts/searchbacking the “Link a storefront” picker. The link state lives inline on the buyer’sinventory_sourcerow — no separate sidecar — and the seller has permission to update thelink_*fields when responding. The link is an authorization handshake only; economic terms (revenue share, scope, exclusivity) are negotiated per-transaction inget_products/create_media_buy, never at link time. - The
/storefrontpage now lives inside a two-tab shell: Inventory sources (the existing unified registry from Path B PR4) and Settings. A page-level header above the tabs surfaces the storefront identity (brand name + handle + “View storefront card” button), and a setup banner tracks the three preconditions to go live — Discovery card (resolved frombrand.json), Inventory source (≥1 connected), and Billing (Stripe Connect). Each banner chip deep-links to the right surface. - The Settings tab covers State (pause/resume), Identity (operator domain + brand.json status), API access (published MCP endpoint), and Billing (deep-linked to the existing
/storefront-billingflow). Visibility, People, Channels, Locale, and Danger sections render as labelled placeholders until their backend wiring lands. - The discovery card modal reads exclusively from the publisher’s
brand.json— if it doesn’t resolve, the modal prompts the publisher to register at agenticadvertising.org (free) rather than offering a manual edit fallback. brand.json is the single source of truth for the discovery card. - The Pause / Resume button in storefront settings is now wired to the API. Pause shows a confirmation dialog since it stops buyer agents from receiving responses to new briefs; resume goes through readiness checks so the same gates that block first-time go-live also block re-activation.
2.99.0 — May 11, 2026 at 8:54 PM UTC
- Add bulk creative upload to the campaign creative assets page. Drop a folder, multi-select files, or a zip and the UI groups them into proposed creatives (one per subfolder, one per loose file, with zips auto-extracted), lets you edit names and remove rows, then uploads them in parallel with per-row progress and retry-failed support.
- Fixed
media_product_listreturningINTERNAL_ERRORwhen an unknownagent_idis passed. The tool now returns a properNOT_FOUNDerror instead. - Password reset now forwards the Firebase
tenantIdfrom the reset-email URL to the backend, fixingINVALID_CODEerrors for multi-tenant users. get_campaignnow returns aperformancesnapshot for each media buy withimpressions,spend,clicks,views,completedViews,conversions,leads, andlastUpdated. The snapshot is refreshed synchronously when sellers push webhook deliveries or when on-demand seller calls fetch fresh data — it represents the latest cumulative totals, not a billing-stable timeseries. For billing-stable daily metrics, continue to use the reporting endpoint.
2.98.0 — May 10, 2026 at 3:18 PM UTC
- Removed the unused
executionConfigfield fromPOST/PUT /api/v2/storefront/inventory-sources. The field was an opaque JSONB pass-through with no consumers; per-execution-type configuration will land as typed fields per integration type when needed. Requests that includeexecutionConfigcontinue to succeed — the field is silently ignored at the schema boundary, matching today’s behavior where it was nulled at the service layer.
2.97.1 — May 9, 2026 at 12:05 AM UTC
- Storefront Go Live checklist now shows agent connectivity/compliance status and hides the Prebid Sales Agent check when irrelevant.
2.96.0 — May 8, 2026 at 6:34 PM UTC
- Fixed a 500 error on
GET /api/v2/buyer/campaigns/:id/productsfor campaigns that have an associated discovery session. - Password reset links no longer auto-verify on page load. Users now click a “Continue to reset password” button before the reset code is checked against the backend. This prevents email security scanners (Microsoft Defender Safe Links, Mimecast, Proofpoint, etc.) from pre-fetching the link and causing the user to see an “expired link” error when they click through. Mirrors the existing signup email verification flow.
2.95.1 — May 8, 2026 at 3:46 AM UTC
- Clarified the Stripe billing copy on the storefront onboarding flow and “Go live” panel to better describe Scope3’s role in consolidated payment processing when sellers opt in or out of Stripe Connect.
2.95.0 — May 8, 2026 at 2:13 AM UTC
- Made storefront billing setup always optional and aligned the buy-side
sync_accountspayload with campaign type and seller billing state. - Seller (storefront):
billing_setupreadiness check now starts as optional for new storefronts. It flips to required (blocker) automatically once a connected agent’s capabilities advertiseagentinaccounts.supported_billing— that’s the buyer-side toggle that asks Scope3 to clear payments, so Stripe Connect becomes mandatory before go-live.- When billing is optional and Stripe is unconfigured the readiness check returns
status: optionalwith description copy warning the seller their sales agent is limited to external agreements with buyers (Scope3 will not clear payments; seller must bill the buyer directly). - When billing is required (some agent supports
agentbilling) the readiness check returnsstatus: missing/partialwithisBlocker: trueand explains why. - The storefront onboarding UI consumes the readiness check directly — the “Set up billing” step’s required/optional label and copy track the server.
- Buyer (media buy execution):
- On every media buy execution, the
billingfield sent tosync_accountsis now resolved per buy: -
ROUTEDcampaigns always sendbilling: operator.
-
DECISIONEDcampaigns against a Scope3-hosted seller without Stripe Connect are forced tobilling: operatorand an internalno_seller_billingflag is logged for ops; the seller’s billing status is never echoed back to the buyer.
-
DECISIONEDcampaigns against a seller with billing honor the buyer’s choice (agentoroperator) when supplied viaexecuteMediaBuyoptions. When the buyer doesn’t specify, the default isagent(Scope3 clears) — the happy path on DECISIONED campaigns.
2.94.0 — May 7, 2026 at 7:01 PM UTC
- Storefront agent picker (
GET /storefront/discover-agents) now only surfaces agents that are actually present in the canonical AAO agent registry. Agents that an operator self-claimed in their AAO operator profile but never registered are filtered out, so the modal can no longer offer agents that the connect call would reject. - The connect-time AAO registry gate on
POST /storefront/inventory-sourcesnow applies uniformly to every caller — the SuperAdmin bypass and thecomplianceBypassedresponse field have been removed. Failing or pending AAO compliance still does not block connecting an agent (going-live continues to be gated by storefront readiness). - Buyer storefronts and product discovery now line up around storefront-level visibility:
GET /api/v2/buyer/storefrontsaccepts avisibilityquery parameter. The defaultvisibility=publiccontinues to return ACTIVE storefronts available to any buyer;visibility=privatereturns ALL storefronts (ACTIVE, PENDING, DISABLED) owned by customers in the caller’s parent org. Buyers can set up credentials, link advertiser accounts, and discover products against any of their parent org’s storefronts regardless of lifecycle state. List and detail responses now include astatusfield on each storefront.GET /api/v2/buyer/storefronts/{storefrontId}no longer 404s when an ACTIVE storefront has no active inventory source — it returns the storefront record with an emptysources[]array. Previously the detail endpoint required at least one wired-up source; that requirement only made sense when the list endpoint hid those rows, which is no longer the case.POST /api/v2/buyer/discovery/discover-productsandGET /api/v2/buyer/discovery/{discoveryId}/discover-productsnow expose a storefront-level filter and no longer acceptsalesAgentIds/salesAgentNames. UsestorefrontIds(integer array, IDs fromlist_storefronts) andstorefrontNames(string array, case-insensitive substring) instead. An empty array on the request is treated the same as omitting the field — both mean “no request-level filter,” and the campaign-level pin is used as the fallback when acampaignIdis also provided.- Campaigns can be pinned to a set of storefronts.
create_campaignandupdate_campaignaccept a newstorefrontIdsfield. When set, everydiscover_productsrun for that campaign auto-applies the pinned filter — buyers don’t need to resend it on each call. Pass an empty array onupdate_campaignto clear the pin. On the campaign response (get_campaign,list_campaigns,create_campaign,update_campaign) the pin is surfaced as a hydratedstorefrontsarray — each entry has the storefrontid,platformId, andnameso the response is renderable without a follow-up lookup. - The
CUSTOMER_SCOPE_REQUIREDerror fromapi_callnow includes the user’s available customers (id + company) and a directive suggestion in its structured payload, so agents can callcustomer_switchdirectly without first callingcustomer_list. - Reporting endpoint cleanup:
- “All time” reporting (
days=0) now returns the actual range of available data (first impression to today) instead of a hardcoded2020-01-01placeholder. The MCP reporting widget initializes from the requested range instead of always defaulting to the last 7 days. - Removed the
breakdownquery parameter fromGET /api/v2/buyer/reporting/metrics. It was a UI-only hint with no effect on the returned data; agents no longer have to ask the user a redundant “how do you want it broken down?” question. The MCP reporting widget’s chart group-by dropdown still works interactively. - CSV exports now round derived metrics (
Spend,eCPM,CPC,CTR,Completion Rate) to at most 4 decimal places, eliminating JS floating-point artifacts like50.00000000000001. - Fixed
/auth/sign-upreturning a misleading “Password is too weak” message when the failure was actually a backend validation error or other unrelated issue. The catch block now matches the structured WorkOSpassword_strength_errorcode instead of the substring “password” appearing anywhere in the error body.
2.93.1 — May 7, 2026 at 12:58 PM UTC
- Fixed ADCP webhook endpoint returning HTTP 500 when a sender’s HMAC signature was invalid. Signature verification failures from the SDK now return HTTP 401 with
UNAUTHORIZEDinstead ofINTERNAL_ERROR. Added a fallback verification path that accepts the legacy rawADCP_WEBHOOK_SECRETso sellers provisioned before the per-agent key derivation rolled out can keep delivering webhooks while their stored credentials are rotated.
2.93.0 — May 7, 2026 at 12:07 AM UTC
- Added managed Prebid Sales Agent (PSA) provisioning for storefronts. New endpoints under
/api/v2/storefront/psaaccept a GAM network code, expose the shared service-account email a publisher must grant access to, and provision a per-storefront PSA tenant against the upstream salesagent Tenant Management API. A newpsa_connectionreadiness check appears in/api/v2/storefront/readiness. Provisioning, test-connection, and deactivation flows are end-to-end whenSALESAGENT_TENANT_API_URLandSALESAGENT_TENANT_API_KEYare configured; without them the endpoints return 503 with a clear “not configured” message. - Add buyer-advertiser routing rules to managed sales agent storefronts. Publishers can now map specific
(operator, brand_house, brand_id)triples to dedicated GAM advertisers and see which buyers in recent traffic are still falling back to the tenant default. New REST endpoints under/api/v2/storefront/psa: GET /mappings— list routing rulesPOST /mappings— create a rulePATCH /mappings/{id}— update a ruleDELETE /mappings/{id}— delete a ruleGET /recent-buyers— distinct buyer triples seen in recent traffic, with the precedence step that won the resolution chain- The storefront homepage gains a “Buyer routing” panel that surfaces both lists side-by-side, with a “Pin to rule” CTA on recent buyers that pre-fills the create dialog.
- Two storefront onboarding cleanups:
- Sync state moves out of the agent card into the dedicated
Importing your inventorypanel below. The card row now shows just operational metrics (workflows, products, packages, creatives) without sync controls squeezed in. The sync panel always renders when the tenant is active and adapts its title to state:Inventory(synced + non-empty),Inventory sync needs attention(synced + empty), orImporting your inventory(running). Refresh button + view-sync-details deep-link live in the panel header. - Setup tasks panel now filters out platform-managed publisher items the upstream emits but the publisher can’t act on in embedded mode (
ad_server_connected,tenant_name,tenant_cname,sso_configuration,multiple_currencies,currency_limits,gemini_api_key,slack_integration,signals_agent). Stopgap until the sales agent suppresses these insetup_tasksforis_embedded=truetenants. Visible items now match what the publisher can actually do — products, principals, creative guidelines, naming conventions, etc. - Hand buyer-advertiser routing back to the sales agent. The Storefront-side
Buyer routingpanel + create/edit dialog and their REST endpoints (GET/POST/PATCH/DELETE /api/v2/storefront/psa/mappings,GET /api/v2/storefront/psa/recent-buyers) are removed. The data lives in the sales agent and so does the management UI — publishers manage routing rules from inside the iframe’s settings/advertisers surface. Storefront keeps the default-advertiser fallback (the one piece publishers commit to early during onboarding); per-buyer mapping work moves entirely upstream. - Inventory sync visibility on the storefront homepage is now honest about empty syncs:
- Item count totaled on the agent card. “Last synced: just now · 0 items” tells the publisher at a glance when something went wrong, instead of “synced just now” implying success.
- Sync progress panel keeps rendering when sync completed but a stream imported 0 items (the “synced but empty” state). Title flips to “Inventory sync needs attention” with a warning explaining common causes and a
View sync details →button that deep-links into the sales agent’s inventory page for per-stream run history and re-trigger. - Per-stream errors surface inline with a red message under the stream name when the upstream reports an error string.
- Storefront onboarding polish from the ad-ops audit:
- Properties panel: redesigned around two big counters (registered + authorized for the chosen agent) with a single gap-aware CTA whose copy adapts to the actual gap (“Authorize Interchange on N more properties”, “Register your properties at AAO”, or “Manage on AAO”). The AAO link now carries
?authorize={agentUrl}&return={currentUrl}so the publisher’s pre-fill and round-trip flow is preserved (assuming AAO honors those query params). - Connect Ad Server dialog: spelled out the GAM service-account onboarding path (
Admin → Access & authorization → Users → New user), the recommended role (Administrator, with Order Manager + Trafficker as a fallback), and the “don’t add it under your personal user settings” gotcha that’s the most common stumble. - House domain + public agent URL are now stamped automatically on the upstream tenant on first provision (operator domain + canonical agent URL), so embedded tenants don’t sit with null platform-managed config.
- Sales agent iframe drops the “Back to storefront” wrapper. The salesagent’s embed-aware breadcrumbs (driven by an
X-Embed-Breadcrumb-Rootheader pointing at the customer’s storefront URL) provide a continuous nav lineage from our app into theirs. - Properties panel on the storefront homepage now always deep-links to AAO’s
/publisher/{domain}page as the canonical “manage my inventory” CTA, regardless of whether the publisher self-hosts adagents.json or has AAO host it. AAO’s publisher page handles the three-way fork (self-host instructions, AAO-hosted CNAME, not-configured) and surfaces the per-agent authorization rollup directly. The self-hosted manifest URL stays visible as informational text so publishers can see where their authoritative file lives. - Storefront homepage now defers publisher and advertiser management to the salesagent’s own screens. A single salesagent tenant can rep multiple publishers (Publisher Partners), and advertiser/principal mapping has its own UI on the salesagent (Principals); duplicating those surfaces on the storefront didn’t fit the multi-publisher model. Removed: the AAO-derived “Properties” panel, the
GET /api/v2/storefront/properties-statusendpoint, the “Pick a default GAM advertiser” dialog, thegamDefaultAdvertiserIdfield onPsaConnection, and the corresponding REST endpoint and DB column. Per-publisher AAO state (property registration, adagents.json verification, agent authorization) and per-buyer advertiser mapping both happen in the salesagent now and surface via itssetup_tasksblock, which the storefront’s Sales agent setup panel renders directly. Each setup-task CTA now correctly deep-links into the iframe at the path the salesagent provided. - Polished the Products stat in the storefront homepage’s agent card. The “Manage” CTA was rendering as a heavy filled button that overpowered the surrounding read-only stats (Workflows, Packages, Creatives). Replaced with a subtle underlined text-link beneath the count so the row stays visually consistent.
- Fixed product discovery returning zero products when sales agents emit responses that fail AdCP 3.0 schema validation. The ADCP SDK no longer silently filters partial-shape products out of
get_productsresponses, and any schema violations on a sales agent response are surfaced as a structured warning log with agent name, product count, and the failing fields. Buyers see the actual products that came back even when an upstream agent omits newly required fields likereporting_capabilities. - Two fixes for the inventory sync surface:
- The
View sync details →button now deep-links to/inventory/browseinstead of/inventory. The/inventoryroute is locked for embedded-mode tenants (Sprint 4 platform-managed-page rework); the actionable diagnostic + manual-sync surface lives at/inventory/browse. - Dropped the
Refreshbutton from the inventory panel header. The Tenant Management API’s/refreshendpoint queues SyncJob rows but doesn’t actually kick off the sync threads (salesagent bug). Pressing it produced a misleading “Refreshing… / last run just now / still pending” state. Until that’s fixed upstream, the panel surfaces a single primary CTA (Open sync page →/Manage sync →) that takes the publisher to the salesagent’s working “Sync All” button. - Storefront onboarding now closes the post-provision dead zone:
- New Importing your inventory panel surfaces the three sync streams (inventory, custom targeting, advertisers) with per-stream status while sync is running. Self-hides once everything’s caught up.
- Default GAM advertiser setup task no longer fires before the advertisers sync completes — picking from an empty cache was a dead-end. The task now waits for
syncs.advertisers.status === 'success'. - Buyer routing panel disables its “Add rule” button and shows a “we’re still importing your advertisers” alert until the same sync finishes, so publishers don’t tap into a form whose advertiser list is empty.
- Storefront customers using the managed Prebid Sales Agent now provision real tenants in the embedded sales agent backend. Previously the request lifecycle fell back to a stub client that returned
service unavailable. Five new env vars (SALESAGENT_TENANT_API_URL,SALESAGENT_TENANT_API_KEY,GAM_SHARED_SERVICE_ACCOUNT_EMAIL,GAM_SHARED_SERVICE_ACCOUNT_KEY_JSON,INTERCHANGE_CANONICAL_AGENT_URL) wire the API to the salesagent service deployed in the same cluster. - Surface managed sales agent product counts on the storefront homepage. The new
productsblock on/api/v2/storefront/psa/status(active / draft / archived counts) flows into a clickable Products stat that deep-links the iframe directly to the sales agent’s/productspage. The launch endpoint now accepts an optionalpathfor path-only deep links (sanitized server-side to prevent escaping the tenant prefix). - Adopt the upstream sales agent’s Sprint 1.8 wire-shape additions:
GET /api/v2/storefront/psa/statusnow returns asetupTasksblock whosepublisher-scope items merge into the storefront homepage’s setup task list. Items the upstream marksplatform-scope are dropped — those represent provisioning gaps Scope3 owns.PUT /api/v2/storefront/psa/default-advertisernow round-trips the value to the sales agent before persisting locally. Upstream errors fail the request instead of being silently swallowed, so the publisher’s chosen advertiser can’t drift between surfaces.POST /api/v2/storefront/psa/refreshproxies straight through to the sales agent’s now-live/refreshendpoint.TENANT_NOT_ACTIVATEDADCP errors raised by the sales agent’s natural-key resolution are surfaced as “Publisher hasn’t finished setup yet.” instead of the raw upstream message.
2.92.0 — May 6, 2026 at 6:44 PM UTC
- Buyers can now configure standing log-level data subscriptions per advertiser and per campaign on the v2 advertiser/campaign endpoints. Use the new
dataDelivery.outputs[]array onPOST/PUT /api/v2/buyer/advertisersandPOST/PUT /api/v2/buyer/campaignsto declare what log-level data to ship (MB_DELIVERY,IMPRESSIONS,CLICKS,VAST_EVENTS,CAPI_ATTRIBUTION,MMP_POSTBACKS,MEASUREMENT), the firing cadence (HOURLY,DAILY,WEEKLY), and the destination. v1 supports GCS only — additional destinations land in a follow-up release. Campaign-scoped outputs override advertiser-scoped outputs bydataDeliveryType. Pass an emptydataDelivery.outputsarray to clear; omitdataDeliveryentirely to leave existing outputs untouched. customer_switchcalled without acustomerId(reset to home) now clears the user’s persisted MCP customer selection instead of overwriting it with the home customer ID. Stateless clients fall back to the JWT-default customer when no overlay is present, so the persisted row was redundant on reset, and leaving the home id written there bypassed the multi-customer mutation guard for users who were exiting a switched context rather than committing to home.- Fixed an issue where users who only had read access on their current customer could not accept an invitation to join another customer. Accepting and declining invitations now both require read-level access, matching the fact that invitation acceptance is a personal action authorized by the recipient’s email.
- Fixed the org switcher hiding organizations the user belongs to as a child customer. When you only had a membership on a child organization (and not its parent), that organization was missing from the “Switch org” list, leaving you stranded after switching to a different org. The dropdown now surfaces those memberships directly so you can always navigate back.
- Fixed
customer_switchMCP tool returningINTERNAL_ERRORwhen switching to a non-existent or inactive customer. The tool now returns aNOT_FOUNDerror for missing or inactive customers, andACCESS_DENIEDwhen the user lacks permission for the target customer. media_buy_executenow returnsNOT_FOUNDinstead ofINTERNAL_ERRORwhen the requested media buy ID does not exist.- Fixed an org-settings navigation bug where users with hierarchical or SuperAdmin access to a parent organization could be redirected back to their child customer instead of landing on the org-settings page.
- Fixed SSO sign-in failures showing a misleading “isAuthError is not defined” message instead of the real authentication error. Failed SSO callbacks now display the actual cause returned by the server.
- Fixed an authentication issue where logging in on
staging.interchange.iowould log the user out oninterchange.io(and vice versa). Auth cookies are now scoped per environment so sessions in one environment can no longer overwrite or invalidate sessions in the other. - Existing buyer customers can no longer log into Interchange unless their customer is in the alpha-opt-in cohort. Buyers who are blocked at login are routed to an inline waitlist on the sign-in page; sellers and SuperAdmins are unaffected. New buyer accounts created via “Add account” by an already-enrolled parent are auto-added to the cohort, so child teammates inherit access without manual onboarding.
- ADCP delivery webhook (
POST /adcp/webhook/...) now responds with400 VALIDATION_ERRORand adetails.validationErrorsarray ({ field, code, message }per issue) when the payload fails schema validation, instead of the previous generic500 INTERNAL_ERROR. This lets sales agents self-diagnose payload mistakes (e.g. uppercasepricing_model: "CPM"when the spec requires lowercasecpm) without needing to contact support. - Hid underlying-agent identifiers from the buyer-facing storefront and account-linking endpoints. Buyers now drive the full register-credentials → discover-accounts → link-account flow in
(storefrontId, sourceId)terms — agent identifiers are never exposed. BuyerStorefrontSourceno longer includesprotocol(MCP/A2A). UserequiresCredentialsto drive registration instead.GET /api/v2/buyer/storefronts/credentials— credentials no longer includeagentId/agentName. Each credential exposes asources[]array of{ storefrontId, storefrontName, sourceId, sourceName }listing the storefront sources it gives access to.accountTypeandupdatedAtare now part of the documented response.registeredBymay benullfor legacy credentials that predate registration tracking.POST /api/v2/buyer/storefronts/:storefrontId/sources/:sourceId/credentials— when the source uses OAuth, the response’soauthobject contains{ authorizationUrl, storefrontId, sourceId, sourceName }instead of{ authorizationUrl, agentId, agentName }.GET /api/v2/buyer/advertisers/:advertiserId/accounts,GET /api/v2/buyer/advertisers/:advertiserId/accounts/available, andPOST /api/v2/buyer/advertisers/:advertiserId/accountsacceptstorefrontId+sourceIdto identify the source.partnerIdis no longer accepted.POST /api/v2/buyer/advertisersandPUT /api/v2/buyer/advertisers/:advertiserId— eachlinkedAccounts[]entry takes{ storefrontId, sourceId, accountId, billingType? }.partnerIdis no longer accepted.- Account responses (
AccountOutput,AccountSummary,AvailableAccountOutput, and the embeddedLinkedAccounton the advertiser resource) no longer includepartnerId/partnerName. They exposesources[]of{ storefrontId, storefrontName, sourceId, sourceName }listing the storefront sources that surface the account. The list can be empty when the underlying source has been deactivated — render those accounts as no longer reachable. - Fixed
/auth/check-email-availabilityso that when the backend rejects an email (for example a typo’d domain or a disposable address), the specific reason is surfaced to the caller as a 400 instead of being swallowed as a generic 500 with no detail. - Fixed
sync_accountsfailing when a sales agent’s capabilities were synthesized from its MCP tool list rather than served from aget_adcp_capabilitiesresponse. The call now retries against a v2-tolerant client instead of surfacing as an error.
2.91.2 — May 4, 2026 at 10:40 PM UTC
- Fixed
get_campaignso themediaBuyIdquery param actually narrows the embeddedmediaBuys[]array when called via the MCPapi_calltool. Previously the filter only worked over REST; through MCP it was silently ignored and the full media-buy tree was always returned.
2.91.1 — May 4, 2026 at 10:03 PM UTC
- Fixed duplicate buttons on the storefront Account setup card. The billing step previously showed both “Connect Stripe” and “Setup” side-by-side; now only the primary action renders while a step is in progress.
- Account discovery for advertisers no longer fails when a sales agent advertises AdCP v3 without declaring
adcp.idempotency.replay_ttl_seconds. The platform now retriessync_accountsagainst a v2-tolerant client instead of surfacing the underlying version error.
2.91.0 — May 4, 2026 at 6:27 PM UTC
get_campaignnow returns amediaBuyRefsarray ({ mediaBuyId, status }per buy) placed early in the response so LLM clients can enumerate every media buy on a campaign even when the heavier nestedmediaBuys[]tail is truncated by their context window.get_campaignalso accepts amediaBuyIdquery param (single value or repeated) that narrows the embeddedmediaBuys[]to just the requested buys without changing the campaign object itself.
2.90.0 — May 4, 2026 at 5:00 PM UTC
- Cleaned up the Go live checklist copy on the storefront onboarding page so each item shows a single concise description instead of a redundant action + status pair.
- Fixed Go-live readiness check showing “Billing — Stripe Connect not configured” for child customers that inherit billing from a parent. The readiness check now resolves billing the same way the storefront billing endpoint does, walking up to the parent customer’s
customer_billingrow when the child has none. - Fixed storefront go-live readiness incorrectly flagging agents configured with
NO_AUTHas missing authentication credentials. Only agents that actually require auth (API_KEY, OAUTH, JWT) now gate go-live. - Fixed three creative format pipeline bugs: the Asset requirements panel now recognizes the
primaryslot as satisfied when a CREATIVE_SOURCE asset is uploaded (instead of always reading “Missing”); the creative preview endpoint normalizes assets before forwarding so the remote sales agent’spreview_creativevalidator no longer rejects them for missingasset_type; and creatives built solely from a URL or webhook now correctly tag that asset as the primary creative source instead of leaving every manifest with no renderable primary asset.
2.89.0 — May 4, 2026 at 4:55 AM UTC
- Storefront onboarding and account configuration improvements.
- Documentation improvements.
2.88.1 — May 3, 2026 at 9:18 PM UTC
- Update SSO configuration page to be under account configuration, and improve documentation.
2.88.0 — May 3, 2026 at 7:26 PM UTC
- OAuth discovery metadata (
/.well-known/oauth-authorization-server,/.well-known/oauth-protected-resource,/.well-known/openid-configuration) and the MCPWWW-Authenticateheader now reflect the hostname the client used to reach the API. Requests toapi.interchange.iogetinterchange.ioissuer/endpoints; requests toapi.agentic.scope3.comcontinue to get the legacy domain. Fixes Claude.ai connector setup at the new domain. - Removed the following v2 endpoints and their corresponding MCP tool operations:
/hypotheses,/test-plans,/allocations,/human-feedback,/learning-cycle/run,/belief-state,/testability, and/learning-records. Measurement source, measurement record, and freshness endpoints remain available.
2.86.0 — May 1, 2026 at 9:03 PM UTC
- Added content moderation guardrails on LLM inputs and outputs. User-supplied campaign briefs (
POST /v2/campaigns,PUT /v2/campaigns/:id) are now screened for prompt-injection, jailbreak attempts, and critical content (hate speech, illegal content, violence uplift) before any LLM call. All LLM provider outputs (Claude, Gemini, Bedrock) pass through an output filter that blocks slurs, CSAM, weapons-uplift, and PII leaks, and counts refusal/identity leaks for monitoring. Content blocked by moderation returns422 CONTENT_MODERATION_BLOCKEDwith structured findings. - The
mediaBuys[]array returned onGET /campaigns/:idnow includes each media buy’sstartTimeandendTime, so buyers and agents can see the media buy’s flight window without a separate call. The media buycreatedAtis now stable across versions: editing a media buy no longer rewrites its creation date, and a backfill aligns existing rows so the live row reflects the original creation timestamp. UseupdatedAt(andvalid_fromon historical version reads) to identify when a specific version was created. As part of this work, campaignallocatedBudgetandunallocatedBudgetare now correct while a media buy update is awaiting approval — previously both versions of the in-flight media buy would briefly count toward the allocated total. - Fixed daily delivery webhooks failing with 403 “Agent does not have access to this resource” for buyers using open-auth partner sales agents (e.g. Ozone, CMI Media Group, Planet Nine VDS). The webhook agent↔customer binding check now allows a customer through when they have at least one media buy on the agent, in addition to the existing case where the customer owns the agent. Resource-level tenant scoping in the downstream handlers is unchanged.
- Versioned agreement URLs now follow a
/agreements/<document>/<version>shape: GET /agreements/terms-of-service/{version}(e.g./agreements/terms-of-service/v3-0)GET /agreements/facilitated-agreement-terms/{version}(e.g./agreements/facilitated-agreement-terms/v1-0)- The previous
/agreements/{version}/terms-of-serviceand/agreements/{version}/facilitated-agreement-termspaths are kept as permanent aliases — they serve identical content (no redirect) so historical PSA links and external bookmarks stay valid. Responses on the legacy paths include aLink: <canonical>; rel="canonical"header pointing at the new shape, so log/analytics tooling can normalize on a single URL. Use the new shape for all new integrations.
2.85.0 — May 1, 2026 at 5:04 PM UTC
- Fixed several documentation bugs found in a follow-up audit. The buyer API reference now shows the correct request body for
POST /advertisers/:advertiserId/test-cohorts(cohortTypeanddefinitioninstead of the non-existenttype/percentage/startDate/endDate) andPUT /advertisers/:advertiserId/measurement-config(mmmEnabled,mmmConfig,incrementalityTestingEnabled,brandLiftEnabled). The reporting endpoint is correctly documented asGET /reporting/metrics(was/advertisers/:id/reporting, which doesn’t exist), with the actual hierarchical response shape. The MCP tools section now accurately lists the six registered tools — includingaccept_tos, which buyers must call after their first403 TOS_ACCEPTANCE_REQUIRED. Removed the phantomhelptool entry. Also fixed shared-router notification paths in both buyer and storefront skill files (/api/v2/notifications/..., not/api/v2/buyer/notifications/...or/api/v2/storefront/notifications/...). Removed phantomPOST /event-sources(only/syncexists) and theaccountPolicyghost field from the storefront skill. Conversion API now correctly shows the requiredaccount: { account_id }field. Added five missing storefront routes to the OpenAPI generator (registered agents listing, agent detail, agent OAuth authorize endpoints, storefront audit logs,PUT /billingadmin update, andPOST /billing/account-session) and regeneratedstorefront-api-v2.yaml. - Bump @adcp/sdk to 6.5.0.
- Pulls in two production-correctness fixes for buyer agents on top of the 6.1.0 pre-send AJV ordering fix:
- 6.4.1 strips top-level
nullenvelope fields (errors,context,ext) before validating v2.5 seller responses, so Pydantic-based v2.5 sellers no longer fail discovery withmust be array/must be object. - 6.4.1 wraps
SingleAgentClient.executeTaskin a try/catch so pre-flight errors (feature validation, endpoint discovery, schema validation, version detection, request adaptation) return{ success: false, status: 'failed', error }instead of throwing — restores the declaredTaskResultcontract for callers likelist_authorized_propertiesagainst v2.5 MCP sellers. - 6.2.0 also ships
decideRetryretry semantics for buyer agents (additive; no callers yet). - Storefront compliance responses (
/storefronts/:id/readiness) gain a newsilentvalue on the per-trackstatusenum: the track was wired but observation-based assertions saw zero resources to attest. Distinct frompass(verified) andskip(didn’t run). - Updates to v2 campaigns that target unsupported downstream sales-agent capabilities are now rejected at the API boundary with a
CAPABILITY_NOT_SUPPORTED(HTTP 422) error, instead of failing mid-flight after partial state changes. The error response includes anunsupported[]array detailing each blocked media buy, the agent, and the missing capability. - Added automatic cascade of appended pacing periods to live media buys via ADCP 3.0
update_media_buy.new_packages. Theupdate_campaignresponse now includes apacingCascadeResultblock reporting per-media-buy outcomes (updated,skipped,failed,unsupported). Only strict appends topacingPeriodsare cascaded; insertions, modifications, and removals continue to require manual new media buys. Sellers that don’t advertiseadd_packagesin theirvalid_actionsare reported asunsupported. - V2 list endpoints (
list_*) now return a fixed summary shape, while detail endpoints (get_*) continue to return the full resource. List rows include identity, display, state, categorization, and at-a-glance scalar signals — embedded child collections, long text, and nested configuration objects are no longer returned on lists. - Summary contracts narrowed across the board. Fields that were previously on list responses but now appear only on
get_*: list_advertisers:description,optimizationApplyMode,campaignBudgetType,linkedAccounts,frequencyCaps,utmConfig,linkedBrandlist_audiences:consentBasis,lastOperationStatuslist_advertiser_accounts:advertiser,billingProxy,house,billinglist_creatives:format_previews,auto_detected_template,message,tracking,html_processing,frequencyCaps, per-asset detailslist_campaigns:brief,mediaBuys,audiences,creativeFormats,frequencyCaps,pacingPeriods,performanceConfig,constraints,fees,mediaBudget,allocatedBudget,unallocatedBudget,products,discoveryId,catalogIdlist_buyer_storefronts: fullsources[]array (replaced by counts)list_partner_agents:customerAccounts[]array (replaced by count)- New derived scalars on list responses (replace previously-embedded arrays):
linkedAccountCount(advertisers),sourceCountandconnectedSourceCount(buyer-storefronts),customerAccountCount(partner-agents),asset_count(creatives),tagCount(allocations). - Behavior change on
list_advertisers: theincludeAccounts,includeBrand, andincludeFrequencyCapsquery parameters are removed (they remain available onget_advertiser). - Wire change on
list_test_plansandlist_hypotheses: responses are now wrapped as{ testPlans, total }and{ hypotheses, total }respectively, to match the rest of v2 (both were previously bare arrays). - Wire-format updates:
list_campaigns:budgetTotalandbudgetCurrencyare replaced by nestedbudget: { total, currency }(matchesget_campaign’s nested shape).list_creatives:sync_syncedandsync_agent_countare replaced by nestedsync_status: { synced, agent_count }(matchesget_creative’s nested shape).Campaign.campaignTypeis now optional. Older campaigns where the type was never recorded will returncampaignType: undefined. Code that narrowed against the previously-required field needs a null-check.- Migration: callers that relied on
array.lengthfor child collections should switch to the corresponding*Countfield; callers needing the full resource should switch fromlist_*toget_*for the resources they care about. - Discover Products MCP widget: surface refine errors as a dismissable banner under the controls row (no longer hidden behind the dropdown), move the selection summary below the product cards, and tighten the radius hierarchy (cards 8px, buttons and nested chips/callouts 4px).
- Discovery sessions are now reused across multiple discovery runs within the same campaign. Each run creates a new search context with its own brief, and products are tagged to the run that discovered them. Added a new
GET /campaigns/:id/productsendpoint (andget_campaign_productsoperation forapi_call) to view all staged products with their discovery context and media buy status. - Links in emails, redirects, and UI navigation now resolve to the correct domain (interchange.io or scope3.com) based on where the user is accessing the platform.
- Fixed a crash on the campaign creative assets page when the manifest or format list responses were not arrays.
- Property lists now accept the full set of AdCP property identifier types — sourced directly from
@adcp/client/typesso the schema stays in lockstep with the AAO property registry. Create / update / check endpoints accept a typedidentifiers: [{type, value}]array; the existingdomains: string[]field remains supported as shorthand fordomain-typed identifiers. Property list responses now include typedidentifiers,unresolvedIdentifiers, andregisteredIdentifiersarrays alongside the deriveddomains,unresolvedDomains, andregisteredDomainsviews. The ADCP resolve endpoint (GET /lists/:listId) and/property-lists/checkendpoint return the typed identifiers. Today the local DB resolves web (domain,subdomain) and mobile/CTV app identifiers (ios_bundle,android_package,apple_tv_bundle,bundle_id,apple_app_store_id,google_play_id,roku_store_id,fire_tv_asin,samsung_app_id); other AdCP types accepted by the schema (DOOH venues, podcast feeds, station IDs, etc.) pass validation but currently fall through tounresolvedIdentifiersuntil corresponding inventory data lands. Non-domain types short-circuit to theassessbucket on/checkpending upstream AAO support. - V2 storefront reporting is now driven end-to-end by AdCP 3.00 capabilities.
- Webhook dispatch on storefront media buys is driven by per-product
reporting_capabilities(supports_webhooks/available_reporting_frequencies/available_metrics) and gated by the seller’smedia_buy.reporting_delivery_methods. If the seller doesn’t advertise"webhook", webhook dispatch is suppressed regardless of product-level capabilities. - Offline (bucket) reporting is now configurable per linked partner account. New endpoint
PUT /advertisers/{advertiserId}/accounts/{linkId}/reporting-bucketsets or clears the bucket; passreporting_bucket: nullto clear. After persisting, the seller is notified viasync_accountsusing the spec-definedpreferred_reporting_protocolfield plus a Scope3 transitionalext.scope3_reporting_bucketextension; if that notification fails, the local row is still updated and the response is 503 with the persisted account in the error details. The same operation is exposed via the v2 MCPapi_calltool as the newupdate_account_reporting_bucketoperation. Seller-provisionedaccount.reporting_bucketvalues returned fromlist_accounts/sync_accountsare also persisted, with buyer-supplied buckets winning on conflict. - When a seller advertises offline-only reporting and no
reporting_bucketis configured for an account, media-buy creation now logs a warning and audit-log marker pointing at the configuration endpoint and proceeds (polling viaget_media_buy_deliveryis always available as a baseline per AdCP 3.0). - The
reportingTypeandreportingPollingCadenceparameters on the agent register tool are deprecated. - Product discovery now skips sales agents whose advertised channel coverage does not overlap with the requested channels, instead of fanning out a request the agent will reject. The skipped agents appear in the per-agent debug output (when
debug=true) with a reason likeAgent does not sell requested channels (supports: display, ctv; requested: social). Failed-agent debug output also includes a newskipReasonfield carrying the human-readable rejection text from the agent, useful for the agents that still respond with an error after passing the pre-filter.
2.84.0 — April 29, 2026 at 11:47 PM UTC
- Customer admins can now remove a member from a customer via the admin members page. Removed members lose access immediately and must be re-invited to regain it.
- ADCP integration upgraded to
@adcp/client5.x with hardened webhook handling and new public discovery endpoints. - New public endpoints
/.well-known/jwks.jsonand/.well-known/brand.jsonfor AdCP RFC 9421 request signing — sellers can verify our outbound calls and resolve our brand profile. UpdateCampaignBodynow rejects explicitnull(previously accepted); send omitted fields instead ofnullto indicate “no change”.billingTypevocabulary updated:brandis nowadvertiser. Existing data is migrated automatically.ComplianceTrackResultSchemano longer acceptsexpected— only the documented values are valid.activate_signalMCP tool now requiresdestinations(minItems: 1) per AdCP v3.- Internal: webhook handlers gain per-tenant + per-agent scoping (
customer_id+sales_agent_idin DB predicates), opportunistic RFC 9421 signing on outbound calls, and improved error surfaces (adcpError,correlationId) propagated from the SDK. - Fixed creative attachment to media buys, which had been silently broken in three independent ways. (1) Uploading a creative to a campaign with existing DRAFT media buys was rejected by Postgres because the auto-link query referenced the UPDATE target inside a
LATERALsubquery; the entire transaction rolled back, leavingmedia_buy.creative_idsandmedia_buy_products.creative_assignmentsunchanged, and execution then skipped sales-agent sync. Eligible product/buy pairs are now resolved in a CTE before theUPDATE. (2) TheautoPublishCreativebrand-domain lookup queried theadvertiser_brandstable (renamed toadvertiser_settings) on a column that never existed, leavingbrand_domainundefined on synced creatives — fixed and the silent catch replaced with an actual log line. (3)update_campaignacceptedmediaBuys[].creative_idsin the request body but the service silently dropped it and overwrote with the campaign’s auto-synced creatives, so buyers had no escape hatch when auto-sync was wrong; the field is now honored verbatim (with the existing format/customer/campaign validation inupdateMediaBuysurfacing any errors) and only falls back to auto-sync when the field is omitted. ThemediaBuys[],mediaBuys[].packages[], andmediaBuys[].products[]schemas now use Zod.strict()so unknown keys (typos, removed fields) fail validation instead of being silently stripped — closes the class of bug that hid #3. - When a sales agent rejects
create_media_buywith anadcp_errorenvelope, surface the agent’s actual error code and message instead of the misleading “Sales agent returned completed status but no packages” protocol-violation error.
2.83.3 — April 29, 2026 at 2:59 AM UTC
- Fixed the campaign creative-upload flow so the “Creatives still required” banner clears once a matching creative is uploaded. Previously, a trailing-slash mismatch in
agent_urlbetween a product’s required formats and the uploaded creative’s format caused the requirement to never be marked satisfied. - Fixed format previews not rendering on the creative detail page for some providers and creative types.
- The “Formatted previews” grid is now driven entirely by the format definition: it no longer hides the entire grid when the manifest has no creative-source asset (which happened for webhook- or URL-only creatives), and per-tile media fallbacks tolerate a missing source asset instead of throwing.
- The agent’s
preview_creativeis now called whenever a format is selected, not just when there are no sized siblings. When both sized siblings (e.g.display_300x250_html,display_728x90_htmlfordisplay_html) and agent-rendered previews are returned, the agent’spreview_url/preview_htmlis merged into each sibling tile by matching dimensions so each size shows the actual rendered creative. - Tile labels and iframe titles now show the format ID rather than the per-render ID.
- Fixed
sync_creativesrequest validation error when syncing creatives to third-party sales agents. Per-package assignments are now sent as the spec-compliant array of{ creative_id, package_id }objects and forwarded on the ADCP request.
2.83.2 — April 28, 2026 at 11:49 PM UTC
- Keep the global navigation header (org/account switcher, notifications, account menu) interactive while the Terms of Service acceptance modal is showing. Previously, the modal blocked the entire page, so a stale ToS on the current org prevented users from reaching any other org or account they had access to. ToS is per-customer, so switching is now a valid path forward without accepting on the current org first.
- Block child accounts from accepting Terms of Service against the parent organization’s contract. When a child account’s effective contract resolves via parent fallback, ToS acceptance is refused unless the request comes from an organization admin. The user info response also surfaces a new
tosBlockedReasonfield so the UI can render the right experience: organization admins see an “Accept for the organization” button, while non-admins see a sign-out modal explaining that an organization admin must accept first. - Fixed creatives being rejected before sync to sales agents because the auto-publish flow was injecting domain assets (
brand_name,impression_tracker,click_url) into the creative payload regardless of whether the format spec actually declared a slot for them. Strict sales agents (e.g. Wonderstruck) reject the creative for unrecognized asset keys, and the same hardcoded asset_ids meant agents that name their slots differently (e.g.brand_text,imp_pixel,clickthrough_url) never got those slots filled. - Replaced the per-field injection logic with a single asset-capability registry that walks the format spec, matches each slot by pattern (asset type + asset_id shape), and writes the resolved value using the asset_id the spec actually declared. Adding a new domain field is now one entry in the registry rather than another bespoke injection block.
- Invite-member error toasts now show only the human-readable message instead of the full JSON error blob (e.g. “Too many invitation requests. Please try again in 15 minutes.” instead of
{"errorCode":"...","errorMessage":"..."}).
2.83.1 — April 28, 2026 at 6:25 PM UTC
- Fixed the Terms of Service acceptance modal not appearing when switching into a member organization that has not yet accepted the latest ToS. The check now correctly distinguishes a SuperAdmin impersonating an unaffiliated customer (bypass ToS) from any user — including a SuperAdmin — switching into a customer they are a member of (must accept ToS for that customer).
2.83.0 — April 28, 2026 at 5:36 PM UTC
- Added public, unauthenticated endpoints to serve Scope3 legal agreements as markdown:
GET /agreements/terms-of-service— latest pinned Terms of Service (currently v3.0)GET /agreements/<version>/terms-of-service— versioned Terms of Service (e.g.v3-0)GET /agreements/facilitated-agreement-terms— latest pinned Facilitated Agreement Terms (currently v1.0)GET /agreements/<version>/facilitated-agreement-terms— versioned Facilitated Agreement Terms (e.g.v1-0)GET /agreements/privacy-policy— Scope3 Privacy Policy- Documents are checked into the repository and versioned in code, so the latest pointer is deterministic per release.
- Fixed two cases where creatives could be silently misrouted on media buys. Product format lookups during creative validation now correctly scope by sales agent and customer, so a creative that doesn’t match the active agent’s product is rejected upfront with a clear validation error instead of being silently dropped at the per-package boundary. Products without declared formats no longer receive every creative; they receive none, surfacing the misconfigured product to the buyer.
- Fixed broken endpoint URLs across the v2 docs and clarified how API versioning works.
- Buyer and storefront REST examples now use the canonical
/api/v2/buyer/...and/api/v2/storefront/...base paths everywhere (previously a mix of/api/buyer/...and/api/storefront/..., which only worked via the 308 redirect alias). Shared endpoints —/notifications,/notification-preferences,/notification-email,/slack-configuration,/service-tokens,/accounts,/accept-tos— are now documented at their correct/api/v2/...(no/buyer/segment) paths. Skill-file and OpenAPI YAML download URLs were updated to the same versioned canonical paths. - Added a Versioning section to the Authentication page explaining the difference between the canonical versioned URLs (
/api/v2/buyer,/mcp/v2/buyer, etc. — pinned to v2 across future major versions) and the unversioned aliases (/api/buyer,/mcp/buyer, etc. — 308-redirect to whatever is currently stable). Corrected two notes in the migration guide and the “Built for Agents” page that previously claimed the versioned URLs auto-roll to latest stable, which is the opposite of how versioning actually works. - Also corrected the discovery POST
budgetexample (scalar number, not{ total, currency }), the creative manifest list endpoint (/creativeManifest), the format catalog endpoint (/formats,/creatives/templates), and the polling example forGET /campaigns/:id/media-buy-status(response shape usesmedia_buys[], not a top-levelstatus).
2.82.0 — April 28, 2026 at 2:14 PM UTC
- Added a storefront activity feed for sellers. A new
GET /api/v2/storefront/audit-logsendpoint returns the recent config and inventory source changes for your storefront, and sellers can now access the feed from the home page under the Organization section. - Exposed the activity feed through the MCP
api_calltool on both the buyer and storefront surfaces. Buyers can now list audit log events via the newlist_activityoperation (GET /api/v2/buyer/audit-logs); the storefrontapi_callroutesGET /api/v2/storefront/audit-logsto the same audit log dispatch. - Synced the storefront API documentation with the live route surface. Removed the legacy Pylon-specific
POST /storefront/notifications/provisionandGET /storefront/notifications/statusendpoints from the storefront skill file and OpenAPI spec, and removedpylonAccountIdfrom any documented response. Communication channel provisioning is configured at the customer/account level and is not part of the storefront onboarding flow, so it is not advertised here. Also corrected the storefront API reference (noDELETE /storefront; clarifiedPOST /storefrontis idempotent), aligned/api/storefront/...examples to the canonical/api/v2/storefront/...form, replaced confidential customer placeholder values withAcme, and fixed the AAO builder URL and the agent compliance shape in the storefront skill file. - Added
GET /api/stripe/payment-method-statusto check whether a customer has a payment method on file. The buyer billing page now surfaces a warning when no payment method is configured, so admins can add one before invoices fail to charge. - Fixed six v2 storefront billing operations that returned “Endpoint not found” through the MCP dispatcher despite being documented: provision Stripe Connect account, get billing config, account status, transactions, payouts, and onboarding URL. The underlying REST endpoints were unaffected.
2.81.0 — April 27, 2026 at 9:05 PM UTC
- Added a customer communication channel flow for support: during signup (or via a new Admin → Support tab / home page prompt) customers can opt into a Slack Connect or Microsoft Teams channel (
ext-agentic-[env-]{customer-slug}-{customerId}). The chosen provider, channel name, and invite state are persisted on the customer. For Slack, the channel is automatically linked to a Pylon account and taggedBuyerorSales agentbased on the customer role. - New endpoints:
POST /api/v2/customer/communication-channel— provision Slack/Teams, or passprovider: nullto declineGET /api/v2/customer/communication-channel— read current provisioning statePOST /api/v2/customer/communication-channel/resend-invite— re-send the invite without re-creating the channel- On provisioning, the channel is auto-populated with configured Scope3 internal support staff (buyer or seller list) and all of the customer’s admins. Same-workspace Slack users are added via
conversations.invite, external admins via Slack Connect; Teams external emails are added as B2B guests via the backing M365 group with retries for Graph propagation lag. - Clarified that the
viewsmetric (in reporting and as an optimization goal) refers to viewable impressions (the MRC-viewable subset of impressions, per AdCP), not raw rendered impressions. Documentation and schema descriptions forviews,completedViews, and theMetricGoal.metricfield have been updated to reflect this and to note that a viewability rate goal can be expressed asmetric: "views"with athreshold_ratetarget. - Embed Stripe invoices and pending transactions directly on the billing page for buyer accounts, storefront accounts, and per-storefront child accounts in collapsible sections.
- Fixed an issue where retrying or rapidly clicking “Connect Stripe” could create multiple orphaned Stripe Express accounts for the same client. Provisioning now uses a deterministic idempotency key per customer, so duplicate requests resolve to the same Stripe account.
- Fixed a duplicate-key error that blocked activating new media buy versions when a sales agent accepted an
update_media_buychange. Status sync now performs the version transition atomically, superseding the old version instead of attempting two simultaneously active rows. New media buy versions also activate immediately when the sales agent’s synchronousupdate_media_buyresponse shows the change is already live, instead of waiting up to an hour for the next status poll. - Fixed inflated reporting metrics on
GET /api/v2/buyer/reporting/metricswhen a media buy had a pending update. Both the active and pending-approval versions were being returned in the breakdown, causing the media buy to appear twice and its metrics to be double-counted in the campaign, advertiser, and grand totals. Pending versions (which have no reporting data) are now excluded from the response. - Notifications are now available to all authenticated customers at
GET /api/v2/notifications. Previously the route was registered only under/api/v2/buyer/notifications, which returnedCUSTOMER_ROLE_DENIEDfor storefront customers and broke the in-app notifications bell on storefront login. The legacy/api/v2/buyer/notificationsREST path has been removed; MCPapi_callpaths are unchanged. - Moved SSO Configuration from the user account dropdown to a new SSO tab on the organization settings page. Existing
/sso-configlinks now redirect to the new tab.
2.80.0 — April 24, 2026 at 8:48 PM UTC
- The Connect agents dialog now offers a “Sign in with AAO” button. Signing in via OAuth adds private and member-only agents registered under your operator domain to storefront agent discovery alongside public agents. The token is used only for the active session and is not stored.
- Renaming a storefront no longer regenerates its
platform_id. The identifier is now stable once assigned at creation, which prevents “A storefront with a matching platformId already exists” conflicts when renaming into a slug another storefront already uses. - Added buyer-side frequency cap configuration (
frequencyCaps) on advertiser, campaign, and creative endpoints. Each cap specifies amaxExposureand a rollingwindow(interval+unit). Single GET always includes active caps; LIST endpoints include them whenincludeFrequencyCaps=trueis passed. CREATE/UPDATE bodies accept an optionalfrequencyCapsarray — omit to preserve existing caps, pass an empty array to clear, or supply a new list to replace. - ADCP webhook endpoint now returns proper HTTP status codes for each failure mode instead of a blanket 500. Malformed webhook payloads return 400 with the underlying error message so senders can see what’s wrong, invalid URL path params return 400, and internal infrastructure failures still return 500.
2.79.0 — April 23, 2026 at 10:47 PM UTC
- Added a notification bell to the v2 app header: opens a dropdown of recent notifications with an unread count badge, mark-as-read on click, and mark-all-as-read.
- Tracking pixel URLs now include the advertiser (seat) ID as an
advidquery parameter alongsidecid(creative) andcamp(campaign). Applies to both ADCP asset tracker URLs and HTML-injected tracking pixels for v2 creatives. - Fixed URL-based creative assets (VAST tags, clickthrough URLs, tracker pixels) so the stored filename is derived from the URL (e.g.
tag.xmlorqawolf.com) instead of the URL type label. Also aligned creative update so VAST URLs are stored withasset_type: VAST, matching creative create — previously updates always stored them asasset_type: URL. - Fixed campaign updates failing with “Creative format validation failed” when a campaign has creatives in multiple formats (e.g. video and display) and is linked to format-restricted media buys. Creatives are now filtered per media buy based on product format compatibility before syncing.
- Fixed campaign creation failing with “No active contract found for customer” when a child customer inherits its contract from a parent. Pricing resolution now walks the parent hierarchy to match the same contract-lookup behavior as the rest of the API.
- Updating a property list now retroactively syncs active media buys for advertisers linked to that list, so sales agents receive the refreshed include/exclude properties without needing to recreate the campaign. The update response includes an optional
cascadeSummarysummarizing how many active media buys were notified. - Fixed the
get_media_buy_statusoperation on the v2 buyer MCP tool. It previously returned “Endpoint not found” through the MCP dispatcher despite being documented in the skill; the underlying REST endpoint was unaffected.
2.78.0 — April 23, 2026 at 12:16 AM UTC
- Campaigns now have a
campaignType(DECISIONED or ROUTED) and the budget total includes Scope3 fees. campaignTypeis required when creating a campaign and immutable after creation.DECISIONEDcampaigns means Scope3 is applying real-time decisioning, optimization, or consolidated invoicing and payment processing operations.ROUTEDcampaigns means the buyer is directly connecting to the seller; they transact and settle directly and do not use Scope3’s real-time decisioning or optimization.- Response includes
mediaBudget(allocatable to media buys) and afeesarray with the Scope3 fee breakdown. - Updating
budgetis rejected if the new media budget drops below the sum of existing media buy allocations, or if by reducing the budget the fee would no longer be payable. - ROUTED campaigns only accept media buys whose sales agents require operator authentication; discovery results are filtered to match when a ROUTED campaign ID is supplied.
- Existing campaigns are grandfathered with
campaignType=DECISIONED, an 8% fee rate or custom negotiated price, withmediaBudgetset equal to the existingbudgetso previous spend capacity is preserved. - Updated the “creatives still required” banner on campaign creative assets to group requirements by creative agent and show per-product “one of [formats]” options, matching how products actually require coverage (at least one creative per product, not per distinct format).
- Corrected the v2 buyer skill and
update_campaignschema descriptions for media buystart_time/end_time. Clarifies that a media buy cannot start before the campaign’sflightDates.startDate, and that pacing periods do not strictly govern media buy dates — media buy dates MAY correspond to a pacing period’sstart/endwhen applicable, but are always allowed to be any dates within the campaign flight, with or without pacing periods.
2.77.0 — April 22, 2026 at 8:49 PM UTC
- Added measurement engine endpoints for managing hypotheses, test plans, measurement sources, measurement records, allocations, human feedback, learning cycles, belief state, testability analysis, measurement freshness, and learning records. Includes filtering by flight ID on hypotheses, date range and geo filters on measurement records, and paginated learning records.
- Fixed AAO compliance gating to handle the current registry contract, where
/compliancereturnsstatus: "unknown"for both unregistered agents and registered-but-untested agents. Registered agents without a graded compliance status now pass through storefront source creation instead of being incorrectly rejected. Added handling for upstream 429 responses on property-list bulk resolution so clients see a retryable 503 instead of a 500. - Fixed capability refresh failing for operator-auth sales agents (e.g. Snap) by always authenticating with the agent-level credential instead of resolving through the per-customer credential chain.
- Prevent agents from conflating campaign and media-buy end dates when a campaign has pacing periods. The v2 buyer skill now documents
pacingPeriodsand states that a media buy’send_timecomes from its pacing period’send, not the campaign flight end date. Strengthened theend_timedescription in the v2 update-campaign schema to reinforce the same rule. - Fixed format details endpoint returning an OAuth token resolution error by restricting the seat lookup for an agent to seats whose credential belongs to the calling customer, preventing a seat from another customer (e.g. a master account) from being selected.
- Fixed a bug in the product discovery MCP view where multiple pricing chips appeared selected on products with duplicate pricing option IDs. The selection state now tracks the option by position rather than ID, so products with identical-shape options (same pricing model) render and select correctly.
- Fixed property list endpoints (
POST/GET/PUT /advertisers/:advertiserId/property-lists[/:listId]) to wrap the response in{ propertyList: ... }as documented in the OpenAPI spec. Previously the endpoints returned the bare property list object. - Inventory source creation now requires the partner agent to pass AAO compliance testing. Agents that are not registered or not passing will be rejected with a validation error; temporary AAO outages return a service-unavailable error so the request can be retried.
- Added
optimization_goalsto media buys. Optimization goals (event-based CPA/ROAS targets or metric-based CPC/completion-rate targets) can now be set on a media buy and are applied to every package at execution time. Exposed via the v2update_campaign→mediaBuysentries. Media buy responses now includeoptimization_goals. - Property lists now accept up to 100,000 domains per create, update, and check request (previously capped at 10,000 for create/update and 1,000 for check). Large requests are chunked server-side against the AAO registry and local database, so clients no longer need to split their own batches. Create and update responses now include a
resolutionSummaryobject —totalRequested,resolvedCount,registeredCount,unresolvedCount,resolutionRate— so buyers can see at a glance how many of their submitted domains will actually target. The check endpoint response adds areportIdsarray containing every registry report generated (one per chunk); the existingreportIdfield remains and equalsreportIds[0]for back-compat. - Property list checks now retry once and surface a
503 Service Unavailablewhen the AAO registry returns transient errors (429 or 5xx), instead of failing with a500on the first blip. Clients that retry on 503 will see fewer spurious failures during registry flakes. - Property list checks now retry once when the AAO registry rate-limits a chunk (HTTP 429) instead of failing the whole request, making large bulk checks resilient to brief registry throttling. System service tokens now also pass SuperAdmin-gated checks so operators can drive admin-only flows (e.g. AAO compliance bypass) end-to-end.
2.76.0 — April 21, 2026 at 10:24 PM UTC
- Fixed storefront go-live button hanging when activating a storefront. Activation no longer runs a synchronous agent compliance probe (up to 60s per agent) and is gated only on setup readiness checks.
- Renamed the
VIDEO_VASTURL asset type toVASTon theurl_typefield for creative URL assets. The UI label and backend enum value now both readVAST. Existing stored rows are migrated to the new value. - Reading a storefront now re-evaluates operator-domain verification against the customer’s (or parent’s) registered domain, so storefronts that were saved before auto-verification was available no longer stay stuck as unverified.
- Storefronts operated by a child customer now auto-verify against the parent organization’s registered domain when the child’s own domain is absent or different, so partner-adapter storefronts no longer require manual verification.
2.75.2 — April 21, 2026 at 7:32 PM UTC
- Fixed a bug where the
descriptionfield on advertisers was silently dropped on create and update, and was never returned from get or list endpoints. - Fixed an issue where newly invited users could not see any seats after accepting their invitation. All users now have implicit access to all active seats within their customer, with permissions derived from their customer-level role.
- Show the Stripe Connect billing dashboard (Account / Balances / Payments / Payouts) for all parent and standalone customers on the Billing settings tab, regardless of customer role. Configure the Stripe publishable key so the embedded Connect components actually load, and surface a clear error if the key is missing instead of rendering empty section containers. Also return users to the Billing settings tab after completing Stripe Express onboarding instead of the legacy admin billing page.
- MCP
api_callnow rejects POST/PUT/PATCH/DELETE requests withCUSTOMER_SCOPE_REQUIREDwhen the session’s user has access to more than one customer and has not calledcustomer_switchfirst. This prevents mutating requests from silently landing on the wrong customer. GET requests are unaffected. Agents must callcustomer_switchwith the intended customerId before any mutating request in multi-customer sessions. Applies to both/mcp/v2/buyerand/mcp/v2/storefront. - Require
bidPricewhen adding auction-priced products to a discovery session, and reject unknownpricingOptionIds at add time. Catches these errors early instead of failing later at campaign execution.
2.75.0 — April 21, 2026 at 4:01 PM UTC
- Added an Activity page for buyers that shows a timeline of actions taken on your campaigns, media buys, and related resources (creations, edits, archives, executions, pauses). Filter the feed by time period, advertiser, and campaign. The
GET /api/v2/buyer/campaignsendpoint now also supports anincludeArchived=truequery parameter for retrieving archived campaigns. - Add pacing periods to campaigns. Campaigns can define time-based spend periods with weights or hard budgets. On execution, products are automatically split into per-period ADCP packages with proportional budgets and period-specific flight dates.
- Fixed a 500 error when deleting creative manifests by removing a reference to a non-existent
archived_atcolumn on thecreativestable. - Fixed creatives not propagating to media buys when an existing creative manifest is updated, and added cascade cleanup when a creative manifest is deleted. Non-DRAFT media buys now correctly create a new pending-approval version and notify the sales agent via ADCP when creatives are removed, so the change follows the normal approval flow instead of silently mutating the active version. An empty creative list is now propagated to the sales agent as a clear-all instruction rather than being skipped.
- Creative upload UI now shows the list of format IDs still required based on the products selected for the campaign. The
GET /campaigns/:campaignId/creatives/templatesresponse now returnscampaign_format_idspopulated from the campaign’s products (sourced from media buys and the discovery session) instead of an empty array. - The
update_campaignandlist campaignsresponses now include the creatives assigned to each media buy and package, so callers can confirm which creatives are linked without issuing a follow-up query. Updating a media buy’s creatives now also populates each package’screative_assignments, filtered by the formats accepted by that package’s product.
2.74.0 — April 20, 2026 at 10:38 PM UTC
- Added
allocatedBudgetandunallocatedBudgetcomputed fields to theCampaignresource returned byGET /api/v2/campaignsandGET /api/v2/campaigns/:id. These expose how much of the campaign budget is currently allocated to active media buys (including performance spend from archived media buys) and how much remains available for new media buys, without requiring clients to sum media buy budgets themselves. - Added a new
GET /api/v2/buyer/campaigns/:campaignId/media-buy-statusendpoint that polls sales agents for the live status of all media buys within a campaign. Also available via theapi_callMCP tool as operationget_media_buy_status. A background sync now periodically reconciles media buy statuses to catch transitions that may have been missed by webhooks. - Fixed customer switching for non-admin users in the MCP integrations. The
customer_switchtool is now available in the v2-buyer and v2-storefront MCP integrations, so any user can switch into a customer they have an active membership on (previously only SuperAdmin users could switch via the admin tool). - Fixed MCP sessions being dropped after 4 hours of active use. Sessions now stay alive as long as there is ongoing activity, matching the intended idle-timeout behavior.
- Fixed
GET /api/v2/buyer/reporting/metrics?view=timeseries&download=trueso the generated CSV now matches the summary export columns plus aDatecolumn, with one row per hierarchy leaf (advertiser → campaign → media buy → package) × day. Previously the export silently returned the summary (hierarchy) CSV with no date breakdown, regardless of theviewparameter.
2.73.0 — April 20, 2026 at 4:14 PM UTC
- Added per-package breakdown to the reporting metrics response. Each media buy now exposes its packages with per-package metrics, and every package includes both
productIdand the human-readableproductName. - Added a
metadatafield to optimization suggestions, allowing arbitrary contextual data to be stored and returned alongside suggestion details.
2.72.0 — April 17, 2026 at 9:04 PM UTC
- Enforce campaign flight date guardrails on
PATCH /api/v2/buyer/campaigns/:id. Updates now reject flight date changes that would conflict with non-DRAFT media buys (start before earliest active media buy, end before a media buy’s start or end). Cascade failures to DRAFT media buys now fail the update instead of being silently logged. - Tracking pixel URLs now always include
{MEDIA_BUY_ID}and{PACKAGE_ID}as DSP-resolved macro placeholders, alongside existing{AXEM}and{TMPX}macros. These values are resolved by the publisher at impression time, allowing creatives and their trackers to be reused across multiple media buys and packages. - Agents now auto-activate when authentication credentials are configured, removing the need for a separate activation step before going live. Added auth credential editing to the storefront seller onboarding flow.
- Exposed four v2 storefront onboarding endpoints through the MCP
api_calldispatcher so AI agents can run the full onboarding flow:POST /storefront/resolve-brand,GET /storefront/discover-agents,POST /storefront/notifications/provision, andGET /storefront/notifications/status.PUT /storefrontvia MCP now also auto-verifiesoperatorDomainwhen it matches the caller’s customer domain, matching the REST behavior.
2.70.0 — April 17, 2026 at 5:05 PM UTC
- Audience sync notification emails now name the specific audiences that were synced and summarise the outcome for each, so recipients can tell at a glance which audience the email is about.
- Campaign execution now returns an error when the linked discovery session is not found, instead of silently succeeding with no changes.
- Fixed media buy creation to default start_time to today when not provided or when the date is in the past. Also auto-corrects stale start_time at execution time to prevent errors from draft media buys created before their execution date.
- Made media buy start_time optional — defaults to campaign start date (if future) or today.
2.69.0 — April 16, 2026 at 9:04 PM UTC
- Allow customers to configure an organization-wide notification email address and manage email notification type preferences from the org settings page.
- Redesigned the buyer reporting table with a “Show percentages” toggle, improved visual hierarchy for advertiser/campaign/media buy rows, and aligned empty states with the design system.
- Fixed an issue where creatives added to a campaign after media buy execution were not assigned to packages on the sales agent side.
- Increased per-audience member limits for the audience sync endpoint from 10,000 to 100,000 for both add and remove operations.
2.68.0 — April 16, 2026 at 3:09 PM UTC
- Fixed re-executing an active campaign with new products for the same sales agent now correctly creates additional media buys instead of silently skipping them.
- Fix customer switching for SELLER accounts by moving role-agnostic routes (accounts, service tokens, notification preferences, contracts, Slack configuration, ToS) from buyer-only router to a shared router accessible by all customer types.
2.67.0 — April 16, 2026 at 1:04 AM UTC
- Fixed an issue where the OAuth authorization popup window would not reliably close after completing authorization. The OAuth completion page now notifies the originating window when authorization is complete, allowing connected sessions to refresh automatically without a manual page reload.
2.66.0 — April 15, 2026 at 8:08 PM UTC
- The Buyer API has been migrated from Sales Agents to Storefronts. The new
GET /api/v2/buyer/storefrontsandGET /api/v2/buyer/storefronts/:storefrontIdendpoints replace the previous sales agents endpoints, returning storefronts with their associated inventory sources and credential/connection status. - Credentials for inventory sources are now registered via
POST /api/v2/buyer/storefronts/:storefrontId/sources/:sourceId/credentials, replacing the previous per-agent credential registration endpoint. - Registered credentials can now be listed via
GET /api/v2/buyer/storefronts/credentials. - API error responses now follow a consistent envelope format:
{ "data": null, "error": { "code": "...", "message": "...", "field": "...", "details": {} } }. Thefieldproperty identifies which specific input caused the error when applicable. - MCP tool errors now return structured error objects with
code,message,field, andsuggestionfields in addition to a human-readable text message, making it easier to handle errors programmatically. - Two new error codes are now documented:
INVALID_STATE(400, operation not allowed in current resource state) andINTERNAL_ERROR(500, contact support). - Fixed an issue where the
agentIdfield was incorrectly included in buyer storefront API responses. - Fixed an issue where buyer storefront queries used an incorrect column, which could cause incorrect results.
- Fixed a bug where users with an invalid customer ID in the URL were not properly redirected to their correct customer context.
- Fixed back navigation, password validation, and rate limiting behavior in the sign-up flow.
- Fixed an issue where parent customer accounts were incorrectly blocked by the buyer/seller role gate.
- Added
productIdto package-level reporting metrics.
2.65.0 — April 15, 2026 at 1:50 PM UTC
- Added new Slack webhook integration endpoints under
/api/v2/buyer/slack-configuration, allowing buyer admins to connect a Slack channel to receive platform notifications. GET /api/v2/buyer/slack-configurationretrieves the current Slack configuration; the webhook URL is masked in the response for security.PUT /api/v2/buyer/slack-configurationcreates or updates the Slack configuration, accepting a webhook URL, enabled state, and a list of notification event types to subscribe to.DELETE /api/v2/buyer/slack-configurationremoves the Slack configuration and stops all Slack notifications.POST /api/v2/buyer/slack-configuration/testsends a test message to the configured Slack channel to verify connectivity.- All Slack configuration endpoints require admin-level access; requests from non-admin users will receive a
403response. - Platform notifications are now automatically delivered to a customer’s configured Slack channel when the relevant event type is enabled.
- Fixed an issue where seller and buyer access permissions were not correctly applied in certain authentication scenarios.
2.64.0 — April 14, 2026 at 10:53 PM UTC
- Added refinement support to the
POST /api/v2/buyer/discovery/discover-productsendpoint: you can now pass arefinearray with adiscoveryIdto iteratively refine discovery results (e.g., “more video options”, omit a product, or get more like a specific product). The response includes arefinementAppliedfield describing how each instruction was handled. - Notification preferences have changed from opt-out to opt-in. The
GETandPUT/api/v2/buyer/notification-preferencesendpoints now use anoptInsfield instead ofoptOuts. Only explicitly opted-in notification types will be delivered. - Fixed a bug where the OAuth callback for storefront partner integrations would show a generic error instead of the actual error message returned by the OAuth provider.
- Fixed an issue where the OpenAPI YAML spec was not resolved correctly in production, which could cause spec-serving endpoints to fail.
- Fixed an issue where trace IDs were being surfaced in user-facing error messages; errors now contain only relevant context.
- Improved error logging for campaign creation failures to surface more actionable debug information.
2.63.1 — April 14, 2026 at 5:01 PM UTC
- The user impersonation list now returns all available users instead of being capped at 50, making it easier to find and select users in larger organizations.
- Format group names in the creative format dropdown now display consistently using the format’s source URL, improving clarity when working with multiple format sources.
2.63.0 — April 14, 2026 at 4:19 PM UTC
- When creating a creative, you can now provide a VAST tag URL directly as a primary asset by selecting the new “URL” tab and choosing the “Video VAST” type.
- Creative creation now supports a “Webhook” tab, allowing you to configure a webhook endpoint (with method, timeout, response type, and optional HMAC or API key security) as the primary creative asset source.
- The
VIDEO_VASTvalue is now supported for theurl_typefield on URL assets when creating creatives via the API. - Fixed an issue where media buy execution could fail incorrectly when the response contained an empty errors array rather than actual errors.
2.62.0 — April 14, 2026 at 3:20 PM UTC
- When a user signs up under an existing customer organization, the relevant customer admins are now notified automatically.
- Products can now be removed from completed discovery sessions, not just active ones.
- Fixed an issue where email notification suppression was not applied consistently across all token types.
- Fixed an issue with creative sync where assignment data was not being formatted correctly, which could cause sync requests to fail or behave unexpectedly.
2.61.0 — April 14, 2026 at 1:47 PM UTC
- The
ARCHIVEDstorefront status has been removed. Storefronts that were previously archived have been migrated toDISABLEDstatus. Valid statuses are nowPENDING,ACTIVE, andDISABLED. - Notification emails for user-initiated actions (such as optimization suggestions) are now sent only to the user who triggered the action, rather than to all users on the account.
- Campaign health events now trigger notifications when a campaign becomes active or transitions away from active status, replacing generic create/update/delete notification events.
- Users who are members of a child account can now see their parent organization and sibling accounts in the customer context list, providing complete hierarchy visibility.
- Tracking pixels now include the
tmpx={TMPX}macro in addition to the existingaxem={AXEM}macro on both impression and click tracker URLs.
2.60.0 — April 13, 2026 at 6:49 PM UTC
- The Storefront API now exposes a full set of signals management endpoints: create, list, get, update, delete, and discover signals (
POST/GET/PUT/DELETE /api/v2/storefront/signalsandPOST /api/v2/storefront/signals/discover). - The storefront
enabledboolean field has been replaced with astatusfield supporting four lifecycle states:PENDING,ACTIVE,DISABLED, andARCHIVED. Clients should update any code that reads or writesenabledto usestatusinstead. - Status transitions are now validated — for example, an
ARCHIVEDstorefront cannot be transitioned to any other state. - The
customerIdfield on the delete user endpoint is now optional; requests without it will succeed rather than returning a validation error. - The
ask_about_capabilitytool now returns complete documentation sections without truncation, ensuring responses include the full context needed to answer capability questions.
2.59.0 — April 13, 2026 at 4:31 PM UTC
- The
api_calltool now supports a namedoperationparameter (e.g.,"operation": "list_advertisers") as an alternative to specifyingmethodandendpointdirectly, reducing the chance of incorrect HTTP methods or malformed paths. - When an
api_callfails due to a malformed endpoint (missing path prefix, trailing slash, etc.), the API will now automatically attempt to correct and retry the request rather than returning an error immediately. - OAuth is now supported when creating or editing inventory sources in the UI.
- Child customer users can now see their parent organization and sibling accounts in the customer selector, enabling easier navigation across accounts in a hierarchy.
- Fixed an issue where email notifications were not being delivered due to missing configuration in the API deployment.
2.58.0 — April 12, 2026 at 9:46 AM UTC
- During signup, the company name field is now pre-filled using a brand registry lookup based on your email domain, replacing the previous email domain parsing heuristic. When a match is found, a confirmation message (“We found your company in the brand registry.”) is shown in the form.
- The
POST /auth/check-email-availabilityendpoint now returns an optionalsuggestedCompanyNamefield in the response when a company name can be resolved from the email domain for new customers. - Rate limiting has been applied to
POST /auth/check-email-availability, consistent with other signup endpoints. - Authentication status checks are now cached client-side for up to 2 minutes, reducing redundant network requests during navigation while maintaining session security.
2.57.2 — April 11, 2026 at 4:39 PM UTC
- OAuth and SSO users signing up will now automatically skip the personal details step, as their name and email are pre-filled from the identity provider.
- Fixed an issue where child accounts could fail to resolve their active contract correctly; child accounts will now properly fall back to the parent contract when needed.
2.57.1 — April 10, 2026 at 11:04 PM UTC
- The
accept_tostool is now available in the v2-buyer and v2-storefront MCP contexts, allowing organizations to accept the Terms of Service before making API calls. - Advertiser API responses now correctly return the
idfield across all advertiser endpoints (list, create, get, update, restore). - Validation error messages for tool inputs now consistently read “Validation error for tool” for clearer error reporting.
- Media buy status filtering now includes
pending_creativesandpending_startstatuses in addition to the existingactive,paused, andcompletedstates.
2.57.0 — April 10, 2026 at 10:21 PM UTC
- MCP tool calls now return clear, descriptive error messages immediately when required fields are missing or field values are invalid, rather than failing later with a less informative error.
- Advertiser API responses now consistently return the advertiser identifier as
idacross all endpoints (list, create, get, update, restore).
2.56.0 — April 10, 2026 at 7:58 PM UTC
- Administrators on a parent organization can now switch into and access child customer accounts without requiring explicit per-account permissions.
- The account list now includes child customers accessible through parent organization hierarchy, so all manageable accounts appear in the customer selector.
- A maintenance banner is now displayed in the application when scheduled or active maintenance windows are configured, showing relevant timing and status information.
- Fixed an issue where switching customer context could result in incorrect access permissions or an inconsistent impersonation state.
- Fixed an issue where child customers now correctly inherit their parent’s contract and Terms of Service when they have no contract of their own.
- Fixed an issue where returning from an impersonated customer session now correctly restores the previous customer context and page location.
- Error messages shown in notifications now display the human-readable message instead of an internal error code when both are available.
2.55.0 — April 10, 2026 at 4:50 PM UTC
- Added notification preference opt-out controls: users can now manage which notification types they receive per channel via
GET /api/v2/buyer/notification-preferencesandPUT /api/v2/buyer/notification-preferences. - In-app notifications now respect per-user opt-out preferences, automatically filtering out notification types the user has opted out of.
- Email notifications now respect per-user opt-out preferences, skipping delivery for users who have opted out of a given notification type.
- Signup flow now accepts only Advertiser and Seller as account types; previously accepted types such as “Agency” and “Other” are no longer valid.
- Invitation requirement for joining an existing organization is now enforced by default for all users, without requiring a feature flag to be enabled.
- The audience sync member removal schema has been aligned with the latest spec; the
externalId,hashedEmail,hashedPhone, anduidsfields are now consistently structured. - Fixed a security issue where an OAuth re-registration could allow one customer’s credentials to be overwritten by another customer using the same account identifier.
- Fixed an issue where switching to a customer account via the API could return users scoped to the wrong customer.
- Fixed authentication callback handling to correctly display a fallback for non-standard auth flows and handle missing customer state gracefully.
- Fixed cross-links on the authentication pages to use correct navigation behavior, preventing unintended full page reloads.
- Fixed Terms of Service and Privacy Policy links on the signup page to render as standard anchor links.
- Fixed the
customer_switchMCP tool to return a clear validation error when a non-numeric or invalid customer ID is provided, rather than an internal database error.
2.54.0 — April 8, 2026 at 9:11 PM UTC
- Users now receive email notifications when new notifications are created, keeping teams informed of important updates without needing to log in.
- A new suggestion apply flow has been added with webhook status tracking, allowing optimization suggestions to be applied and their progress monitored end-to-end.
- Discovery session activity is now logged for analytics, enabling better insights into marketplace search and product interactions over time.
- The UI now preserves the intended destination path through account resolution, so users are correctly redirected to their original target after authentication.
- Packages are now associated with a single product via a direct relationship, improving consistency and reliability of package-product data.
2.53.0 — April 8, 2026 at 2:14 PM UTC
- Added a new endpoint
POST /api/v2/buyer/advertisers/:advertiserId/measurement-data/syncfor syncing advertiser performance measurement data to the ingestion pipeline. - Unversioned API paths
/api/buyerand/api/storefrontnow permanently redirect (308) to their versioned equivalents/api/v2/buyerand/api/v2/storefront. - The
sourcefield on measurement data objects now accepts only the valuesadvertiser,mmp, ormeasurement_partnerinstead of any free-form string. - A new optional
source_metric_namefield is available on measurement data objects for mapping raw partner metric names. - Trace context (
traceparent) and MCP session ID headers are now propagated to all downstream service calls, improving end-to-end request traceability. - Fixed a bug where customer-level API users were incorrectly blocked from updating or deleting campaigns that belong to a specific seat within their organization.
- Fixed a data corruption issue where brand profile URLs were being double-serialized, which could cause campaign execution to fail or send malformed data.
- Fixed a bug where the
brand_manifestURL field was not validated, allowing invalid values to be stored and forwarded. - Improved error messages when a tactic cannot be created because no brand is linked to the campaign, replacing a technical internal message with a clearer user-facing explanation.
- When creating an advertiser, the brand is now automatically saved without requiring a separate “Register & Create” action.
2.52.0 — April 7, 2026 at 4:18 PM UTC
- Added new optimization suggestion endpoints to the Buyer API, allowing you to list, view, approve, and reject AI-generated optimization suggestions for your media buys via the
api_calltool. - Expired OAuth tokens are now automatically refreshed when resolving agent accounts, reducing authentication failures for OAuth-connected integrations.
- API responses now include an
x-trace-idheader, making it easier to correlate requests with support when troubleshooting issues. - Fixed a bug where the campaign optimizer job used an incorrect argument format, which could cause optimization runs to fail silently.
- MCP sessions are now reliably consistent across server instances, eliminating cases where customer switches or seat selections made on one server were not reflected when requests routed to a different server.
2.51.0 — April 6, 2026 at 5:38 PM UTC
- Added a new testing endpoint
POST /api/v2/testing/deleteSsoConnectionthat allows deletion of all SSO connections for a given WorkOS organization ID, returning 204 whether connections existed or not (idempotent). RequiresSUPER_ADMINauthentication. - Seat-scoped API tokens now automatically infer the advertiser ID, allowing use of
/advertisers/me/in endpoint paths as a shorthand that resolves to your token’s advertiser. Explicit advertiser IDs in requests are validated against the token scope and will return a clear error on mismatch. - Advertiser account linking now returns a validation error immediately if any requested account is not found or has a sandbox/production mismatch, rather than silently skipping the invalid accounts.
- Fixed a bug where the
deleteUsercleanup endpoint would return a502error if the backend deletion step failed; the operation now completes successfully and reports the partial result. - Non-OAuth inventory source agents are now created in
PENDINGstatus instead of being auto-activated on inventory source creation. - Fixed the Terms of Service modal so the ToS link is now clickable and opens correctly.
- Fixed an issue where
isCustomerSwitchedwas not correctly detected for member-level customer switches, ensuring contract and ToS enforcement behaves correctly when switching between customers. - The measurement config API list endpoint now uses
limitinstead oftakeas the pagination parameter, and response data is accessed atdata.data.items.
2.50.1 — April 3, 2026 at 6:50 PM UTC
- Fixed an issue where the
authConfiguredfield on storefront agent responses could incorrectly reflect a non-existent configuration source, ensuring it now accurately indicates whether authentication is set up.
2.50.0 — April 3, 2026 at 5:58 PM UTC
- Inventory sources can now be edited after creation, including updating the endpoint URL, protocol, authentication type, and credentials.
- A new hosted sales agent setup flow is available when creating inventory sources, simplifying agent onboarding.
- Agents associated with non-OAuth inventory sources are now automatically activated upon source creation, removing the need for a manual activation step.
- A new
GET /billing/accountsendpoint is available for parent customers to view billing status across all managed child accounts. - Billing configuration is now scoped to the customer account rather than the storefront, enabling more consistent billing management across storefronts.
- Parent customers can now accept the Terms of Service directly without needing to switch accounts first.
- The Terms of Service acceptance flow now automatically provisions the required contract, removing a manual step that previously blocked new customers.
- The ToS enforcement error code has been unified: all cases where ToS acceptance is required now return
TOS_ACCEPTANCE_REQUIREDinstead of the previousCONTRACT_REQUIREDcode. - Fixed an issue where customer session context (including account type) was not correctly persisted when switching between parent and child accounts.
- Fixed a bug where parent-account access restrictions were incorrectly applied after switching away from a child account.
- Fixed a bug where a missing
bid_pricefield in campaign execution returned an unformatted error; it now returns a clear validation error. - Fixed an issue where products added via product IDs were missing the
bid_pricefield. - Fixed an issue where the
generation_promptasset status and creative brief were not resolving or clearing correctly. - Fixed a bug where tactic creation failed when no agent was associated with the campaign.
- Fixed an issue where the SSO configuration feature flag was not evaluated for super admins and sellers.
- Fixed distributed tracing context propagation so tool call spans are correctly linked to their originating HTTP request.
2.49.0 — April 2, 2026 at 4:45 PM UTC
- The buyer campaigns list endpoint now supports an
includeMediaBuysquery parameter (true/false); when enabled, each campaign in the response will include its associated media buys with products, packages, and delivery data. - The Creative Assets page filters (Advertiser, Campaign, Creative) have moved into the page header, and the Campaign dropdown no longer requires selecting an advertiser first — you can now search campaigns independently.
- Selecting a campaign in Creative Assets will automatically resolve and set the matching advertiser, improving navigation flow.
- The billing readiness check on the Storefront page is now clickable for admin users, navigating directly to the billing settings page.
- Org settings now support deep-linking to a specific tab via a
?tab=query parameter (e.g.?tab=billing), and tab changes update the URL accordingly. - Fixed an issue where media buys were missing from the buyer campaigns list response.
- Fixed an issue where accounts with a
restrictedbilling onboarding status were not shown the onboarding card to complete their Stripe setup. - Fixed a loading state issue on the billing page where content would not show a skeleton placeholder immediately on load.
- The onboarding card for billing now shows a different message for accounts that have a partially connected Stripe account, prompting them to finish setup.
2.48.0 — April 2, 2026 at 2:13 PM UTC
- Storefront readiness status now surfaces partial states and failure details, giving you clearer visibility into why a storefront check did not fully pass.
- Creative assignments are now reliably tracked per product based on format compatibility, ensuring the correct creatives are associated with each product in a media buy.
- Super admins now correctly bypass the alpha opt-in feature flag, giving them full API access without needing explicit flag enrollment.
- Compliance track results now include an optional
failureReasonfield in the API response, explaining why a track failed or only partially passed.
2.47.0 — April 1, 2026 at 8:10 PM UTC
- When creating a storefront, the
platformIdis now automatically generated from the storefront name (e.g. “CVS Media” becomescvs-media), so you no longer need to provide it manually. - Campaign creatives are now automatically synchronized to media buys when a campaign is updated, removing the need to manage creative assignments manually.
- Product discovery now uses your storefront’s configured inventory sources first, with a fallback to the broader agent catalog, so buyers see a more curated and relevant set of products.
- Storefront compliance checks now load asynchronously, reducing wait times when accessing storefront readiness information.
- A new endpoint
GET /api/v2/buyer/creative-dashboard-url?advertiserId={advertiserId}&campaignId={campaignId}returns a fully-resolved URL for managing creative assets, replacing the previous two-step lookup flow. - Fixed an issue where the contract page incorrectly displayed “No active contract” even when an active contract existed.
- Fixed the discover products selection bar and recommended plan flow to behave correctly.
- Fixed an issue where switching customers did not redirect to the homepage; role-based route guards are now enforced on navigation.
- The advertiser status filter has been moved to the page header dropdown for easier access.
2.46.0 — April 1, 2026 at 1:09 AM UTC
- Non-admin users can now list accessible customers and switch between customer contexts via the MCP
customer_listandcustomer_switchtools, without requiring administrator privileges. - Media buys can now be canceled or archived directly through the campaign update endpoint (
PUT /api/v2/buyer/campaigns/{id}) using the newactionfield ("cancel"or"delete") in themediaBuysarray. - The
/toolsendpoint now enforces Terms of Service acceptance, returning aTOS_ACCEPTANCE_REQUIREDorCONTRACT_REQUIREDerror if the organization has not completed onboarding requirements. - Localhost URLs are now permitted for storefront agent registration when running in a development environment, enabling local agent testing.
- Fixed an issue where account API keys were not displaying correctly and new key creation was failing.
- Fixed a bug where the storefront MCP endpoint was not mounting correctly following a recent rename.
- Fixed an issue where switching organizations from the org settings page did not navigate to the home page as expected.
- Fixed a bug where the admin portal could be incorrectly redirected to a customer-scoped URL.
- Fixed an issue where media buy cache was not invalidated after product budget updates, causing stale data to be returned.
- Fixed a bug where Terms of Service enforcement could be bypassed when switching accounts.
- Fixed format previews not displaying for certain creative types.
- Fixed upstream error details not being forwarded correctly in event logging responses.
- The
confirmStandaloneConversionfield has been removed from the child account creation request body; standalone conversion now happens automatically. - The Storefronts section has been renamed to “Storefront” in the UI and now includes an edit dialog.
2.45.0 — March 31, 2026 at 3:46 PM UTC
- When a new seller account is created, a default storefront is now automatically provisioned for that account.
- Existing seller accounts with a single active sales agent have been retroactively provisioned with a default storefront.
- When a sales agent is registered, a storefront and inventory source are now automatically created for the seller if one does not already exist.
- Product discovery responses now include empty result groups for sales agents that were successfully queried but returned no matching inventory, making it clear the agent was reached but had no products to offer.
- When a sales agent returns zero products during discovery, the response now includes a message indicating no matching inventory was found and suggests adjusting the brief, budget, or filters.
- Fixed an issue where empty results from a sales agent during product discovery were indistinguishable from a null or failed response.
- Failed sales agent queries are no longer surfaced to end users in discovery summaries; only successful agent results are shown.
2.44.0 — March 31, 2026 at 2:19 PM UTC
- OAuth redirect URIs can now be managed dynamically, enabling faster onboarding of new integration partners without requiring a service deployment.
- Access to MCP and API features is now gated behind an alpha opt-in flag, allowing gradual rollout to eligible users.
- The buyer assistant AI has been updated with additional guardrails to reduce inaccurate or fabricated responses.
- Fixed an issue where an empty dropdown in the Creatives section was not labeled clearly and could not be clicked.
- Fixed an issue where the Creatives card was incorrectly visible to seller users on the home page.
2.43.1 — March 30, 2026 at 10:19 PM UTC
- The Event Sources API has been streamlined: individual create, get, update, and delete endpoints have been removed in favour of the sync (
POST /api/v2/buyer/advertisers/:advertiserId/event-sources/sync) and list (GET /api/v2/buyer/advertisers/:advertiserId/event-sources) endpoints only. - Fixed an error on the reporting page that caused it to fail to load metrics data correctly.
2.43.0 — March 30, 2026 at 9:15 PM UTC
- The Partner API has been renamed to the Storefront API. All endpoints previously under
/api/v2/partner/are now available at/api/v2/storefront/, and requests to the old path will be automatically redirected. - The MCP endpoint for the Storefront API has moved from
/mcp/v2/partnerto/mcp/v2/storefront(and/mcp/partnerto/mcp/storefront). - A new
GET /api/v2/buyer/advertisers/{advertiserId}/events/summaryendpoint is available, returning hourly-aggregated event counts (impressions, clicks, conversions, measurements, and MMP events) for an advertiser. Supports optional filtering by event type and custom date ranges. - The events summary endpoint defaults to the last completed UTC hour when no date range is specified, and event data may take up to 1 hour to appear after being reported.
- Two new audience notification event types (
audience.syncedandaudience.sync_failed) are now supported and will be delivered via the notifications system. - All authenticated pages now include the customer ID in their URLs (e.g.,
/208/reporting), making links shareable across users and customer contexts.
2.42.0 — March 30, 2026 at 3:32 PM UTC
- The default UTM parameters applied to advertiser landing page URLs have been updated to better align with GA4 standards:
utm_mediumis now included with the valueagentic, and the creative parameter now uses the standardutm_contentkey instead ofutm_creative. - Fixed an issue where the Advertisers management table appeared empty even when data was successfully returned by the API.
2.41.0 — March 30, 2026 at 3:50 AM UTC
- The Creative Manifest API (v2) is now available, enabling campaign-scoped management of creative assets including HTML processing, format previews, ADCP template detection, and tracking pixel support. Manifests are created and uploaded via the dashboard UI; list, get, update metadata, and delete operations are available via the API.
- Audience sync now delivers a push notification webhook to the buyer upon completion. Provide a
pushNotificationConfig(withurl,authentication, andtoken) in the sync request body to receive the callback. - Storefronts now enforce a readiness gate before going live: setting
enabled: truereturns a400error if required readiness checks are not yet passing. Settingenabled: falseis always allowed without restriction. - Inventory source registration now makes
sourceIdoptional. When omitted, asourceIdis automatically generated from thenamefield (e.g."Auto Generated Source"becomes"auto-generated-source"). - The Conversion Events API (
/advertisers/{advertiserId}/conversion-events) has been removed. Conversion tracking is now handled via event sources; useGET /advertisers/{advertiserId}/events/summarywithtype: "conversion"to view available events for optimization. - Fixed a bug where property list responses contained incorrect data and missing entries. Properties are now sourced from an updated registry for improved accuracy.
- Fixed an issue where per-agent discovery errors were silently swallowed; they are now surfaced in debug output for easier troubleshooting.
- Fixed an issue where the Create Storefront modal opened automatically on page load.
2.40.0 — March 27, 2026 at 12:26 AM UTC
- The
POST /api/v2/buyer/accounts/create-childendpoint now requires acustomerRolefield (BUYERorSELLER) when creating a child account. - Creating a storefront no longer requires a
platformId— if omitted, one is automatically generated from the storefront name. - A new storefront billing page is available, providing Stripe Connect integration for sellers to manage payments, payouts, and balances.
- A new storefront management page is available, showing readiness checks and configuration status for your storefront.
- Discovery card product listings now include biddable pricing indicators and updated fonts and styling.
- The
advertiser_idfield has been removed from the measurement data request body; it is now taken from the URL path parameter and injected automatically. - Pricing option data now includes a
priceGuidanceobject with floor, p25, p50, p75, and p90 price percentile fields when available. - Fixed an issue where media buy requests were not compatible with older publisher versions; the
buyer_reffield is now sent in the expected format for all publisher versions. - Fixed an issue where the customer dropdown was disabled and not properly visible during superadmin impersonation sessions.
- Fixed an issue where the billing page did not prompt users to set up a storefront when none existed.
- The OAuth redirect URI for
bayes.fly.devis now supported.
2.39.0 — March 26, 2026 at 1:19 PM UTC
- Added a new
POST /api/v2/buyer/advertisers/:advertiserId/log-eventendpoint for ingesting conversion and marketing events (purchases, leads, page views, etc.) with support for user matching, custom data, and test event codes. - Added a new
POST /api/v2/buyer/accounts/create-childendpoint allowing admin users to create child accounts under their organization hierarchy, including support for converting standalone accounts. - The
GET /api/v2/buyer/campaignsendpoint now accepts amediaBuyStatusfilter parameter (single value or array) to narrow campaign results by the status of their associated media buys. - The
resolve-accountresponse now includesendpointUrlandauthenticationTypefields. - Users with pending invitations are now automatically routed to the correct customer organization during signup, and the email availability check response now surfaces
pendingInvitationswhen applicable. - Added a
POST /api/v2/buyer/campaigns/:id/reactivateendpoint to reactivate a paused or stopped campaign and cascade the update to its associated media buys. - The property list resolve endpoint has moved from
GET /api/v2/buyer/property-lists/:listId/resolvetoGET /lists/:listIdto align with the expected URL convention used by sales agents. - Audience webhook payloads now use
camelCasefield names consistently. - Fixed an issue where users signing up for an existing domain with a pending invitation could be incorrectly blocked from completing registration.
- Reduced the per-agent discovery timeout from 90 seconds to 30 seconds, resulting in faster error responses when an agent is unreachable.
- The
MediaBuyStatusenum now includesCANCELEDandINPUT_REQUIREDas valid values across relevant API responses and filters.
2.38.0 — March 25, 2026 at 11:36 AM UTC
- Advertisers now support configurable UTM parameters (
utmConfig) at creation and update, allowing you to define custom tracking parameters appended to landing page URLs during clickthrough. Defaults (utm_source,utm_medium,utm_campaign,utm_content,utm_media_buy,utm_package) are applied automatically if no config is provided. - Campaigns now support a
utmConfigfield to set campaign-level UTM parameter overrides, which take precedence over advertiser-level defaults for matching parameter keys. UsedeleteMissing: truefor replace mode, or omit it for additive updates. - Storefront readiness checks now include live agent compliance results, giving you richer diagnostics on agent connectivity and compliance status.
- Discovery product browsing now caches enrichment results (descriptions and relevance summaries) across requests, so repeated browses within the same session return consistent, faster results.
- Fixed an issue where media buy validation errors (such as invalid dates, missing fields, or budget problems) were incorrectly treated as server errors instead of client errors, resulting in cleaner, more actionable error messages.
- Fixed signal tools failing when no seat was selected.
- Fixed an issue where the tracking endpoint used an incorrect authentication key, which could cause measurement sync requests to fail.
2.37.1 — March 24, 2026 at 5:48 PM UTC
- The Storefront API endpoints have been simplified: all storefront and billing routes now use
/storefront(singular) instead of/storefronts/:platformId, since each customer has exactly one storefront. TheplatformIdpath parameter is no longer required for any storefront, billing, or inventory source operations. - The
GET /storefrontendpoint now serves as the single way to retrieve your storefront, replacing both the previousGET /storefrontsandGET /storefronts/:platformIdendpoints. - Billing endpoints (
/storefront/billing,/storefront/billing/connect,/storefront/billing/status, etc.) no longer includeplatformIdin their responses. - Fixed an issue where users who had already been migrated to the new authentication system would receive an unhelpful error during login; they now correctly receive an “invalid credentials” response instead of being sent through a redundant migration flow.
- Improved the error message shown when account setup fails during login migration — the message now suggests resetting your password and no longer references internal migration processes.
- System tokens now have full administrative access when using the
customer_switchtool, resolving an issue where those operations were incorrectly restricted.
2.37.0 — March 24, 2026 at 12:28 PM UTC
- Added a new
POST /api/v2/buyer/syndicate-audienceendpoint that triggers an audience syndication backfill. On success, it returns a202 Acceptedresponse with anoperationId(UUID) that can be used to track the operation. - Fixed the request body format sent to the audience sync endpoint to use camelCase field names, aligning with standard API conventions.
2.36.0 — March 24, 2026 at 8:14 AM UTC
- Added a new suggestion data structure to support optimization recommendations linked to campaigns and media buys.
- Fixed an issue where product selection in the media planning interface could break due to a field naming mismatch, causing pricing options and biddable products to not display or behave correctly.
- Clarified API documentation to distinguish between using the
demoflag (to return synthetic demo data) versus filtering reporting results by an advertiser or campaign whose name contains “demo”. - Fixed incorrect endpoint references in the v2 partner API documentation to match the actual available endpoints.
2.35.1 — March 24, 2026 at 1:06 AM UTC
- Reporting CSV exports are now available via the REST API using the
?download=truequery parameter on the reporting metrics endpoint; the response includes adownloadUrl,fileName, and an expiration timestamp valid for 7 days. - Fixed a bug where the
offset(andlimit) pagination parameters were being ignored when listing advertisers through the API; pagination now correctly respects these values. - Fixed MCP session errors that could cause requests to fail when a client reconnected or sent requests before completing the initialization handshake.
- Fixed MCP App UI rendering issues related to how widget display domains are resolved for different AI client types.
2.35.0 — March 23, 2026 at 3:59 PM UTC
- Storefront billing is now available via Stripe Connect. Partners can provision a connected account, complete onboarding, and view account status, balance transactions, and payouts through new endpoints under
/api/v2/partner/storefronts/{platformId}/billing. - Storefronts now accept an optional
publisherDomainfield (e.g."cvs.com") on create and update, used for Stripe Connect business profile setup. - Notifications now include a
statusfield (success,error,warning, orinfo) and can be filtered by status when listing. - Service tokens can no longer be created using another service token — token creation now requires a user context. Requests authenticated with a service token will receive a
400error if they attempt to mint new tokens. - Fixed an issue where seat invitations were not visible immediately after login. Invitation processing now completes before the auth response is returned.
- Fixed an issue where seat auto-assignment was not triggered when inviting a new customer member via the v1 invite flow.
- Fixed an OAuth session loop and stuck callback page that could occur during MCP authentication.
- Fixed an issue where MCP session IDs provided in an invalid format were silently accepted, which could cause sessions to fail to persist correctly. Invalid session IDs are now rejected early with a warning.
- Fixed a race condition in SSE connections where heartbeat writes could trigger a headers-already-sent error.
- Fixed MCP request IDs not being consistently propagated across the full session lifecycle, improving log correlation.
- The advertiser list endpoint now returns more results per page, matching what the UI displays.
- ChatGPT plugin OAuth now correctly supports dynamic redirect URIs, resolving authentication failures for ChatGPT-initiated OAuth flows.
2.34.1 — March 21, 2026 at 12:52 AM UTC
- Improved reliability of real-time streaming (SSE) connections by reducing the frequency of keepalive signals, preventing unexpected disconnections that some clients were experiencing during MCP sessions.
2.34.0 — March 20, 2026 at 11:12 PM UTC
- The List Advertisers endpoint (
GET /api/v2/buyer/advertisers) now returns a paginated response withitems,total,hasMore, andnextOffsetfields instead of a flat array with separatemeta.paginationwrapper. - Pagination parameters for the List Advertisers endpoint have changed from
take/skiptolimit/offset, with a maximum page size of 10. - The user management API now supports multi-customer views, returning each user’s memberships across all accessible child customers instead of a single permission level per user.
- Inviting a user to a specific child customer is now supported via the optional
targetCustomerIdfield on the invite endpoint. - Updating a team member’s role now accepts an optional
customerIdfield, allowing parent account admins to update roles on child customer accounts. - The measurement data sync endpoint (
POST /api/v2/buyer/advertisers/{id}/measurement-data/sync) has updated field names:start_date/end_dateare nowstart_time/end_time, andevent_id/event_valueare nowmetric_id/metric_value. - The measurement data sync endpoint now requires
metric_id(from a fixed set of supported metrics),unit(currency, count, ratio, or percentage), and at least one entity identifier (advertiser_id,campaign_id,media_buy_id,package_id, orcreative_id). Currency code is required whenunitis"currency". - Fixed an issue where campaigns in terminal states could be incorrectly re-executed; campaign status is now preserved correctly on failure.
- Fixed incorrect data returned by the measurement configuration API.
- The
POST /api/v2/buyer/accounts/create-childendpoint has been removed.
2.33.0 — March 20, 2026 at 9:06 PM UTC
- The List Advertisers endpoint (
GET /api/v2/buyer/advertisers) now returns a paginated response withitems,total,hasMore, andnextOffsetfields instead of a flat array with separate pagination metadata. - Pagination parameters for List Advertisers have changed from
take/skiptolimit/offset, with a maximum page size of 10. - The Measurement Data Sync endpoint now uses updated field names:
start_time/end_time(replacingstart_date/end_date),metric_id/metric_value(replacingevent_id/event_value), and requires aunitfield (currency,count,ratio,percentage). Whenunitiscurrency, a 3-letter ISO 4217currencycode is required. - Measurement Data Sync now accepts additional optional fields:
source,source_platform,external_row_id, andadvertiser_id. At least one ofadvertiser_id,campaign_id,media_buy_id,package_id, orcreative_idmust be provided per measurement object. - The
POST /api/v2/buyer/accounts/create-childendpoint has been removed. - Fixed an issue where campaign execution could be triggered when a campaign was already in a terminal state; campaign status is now correctly preserved on failure.
- Fixed an issue where completed media buys had an incorrect
valid_tovalue set, which could affect versioning and data accuracy. - Fixed MCP session authentication so that session state is reliably consistent across server instances, improving stability for multi-turn agentic workflows.
- The User Management tool now supports multi-customer access, allowing parent account admins to view and manage users across their child accounts in a single call.
- Member invitation now accepts a
targetCustomerIdparameter, allowing parent admins to invite users directly to a specific child customer. - Updating a member’s role now accepts an optional
customerIdparameter, allowing parent admins to update roles on child customer memberships directly.
2.32.0 — March 20, 2026 at 3:31 PM UTC
- Added a new
POST /api/v2/buyer/accounts/create-childendpoint that creates a child account under the authenticated user’s organization. Requires ADMIN role; automatically promotes standalone accounts to parent accounts and grants the requesting user admin access on the new child. - The customer switcher in the application now includes a “New Account” option for eligible admin users, allowing child account creation directly from the navigation menu.
- The API keys page has been updated with an improved layout, clearer section titles and descriptions, and tabs for switching between personal and organization keys.
- Dialog titles for API key actions have been updated to use consistent casing (e.g. “Edit API key”, “Delete API key”, “API key created successfully”).
- The “Delete API key” confirmation dialog now displays a cleaner confirmation message and uses a more appropriate button style.
- The API key secret dialog now shows a “Copied” confirmation tooltip when the token is copied to clipboard, and displays a clearer security warning message.
- The API keys list now displays up to 50 keys per page, up from 20.
- Fixed a layout issue on the API keys page where the list could overflow the screen; it now sizes to fit its content correctly.
2.31.0 — March 20, 2026 at 11:56 AM UTC
- The
GET /api/v2/buyer/campaigns/{campaignId}response now includesdiscoveryId,products, andproductCountfields for campaigns in DRAFT status, reflecting the products selected during the discovery workflow. These fields are not present on campaigns that have been executed. - API requests to v2 REST routes are now blocked with a
403error if your organization has not accepted the Terms of Service or does not have an active contract. Affected responses will include an error code ofTOS_ACCEPTANCE_REQUIREDorCONTRACT_REQUIREDrespectively. Account and contract management endpoints remain accessible regardless. - Fixed an issue where pricing type detection could behave incorrectly in certain v2/v3 pricing scenarios, which may have caused errors when creating or executing campaigns with some pricing configurations.
2.30.0 — March 20, 2026 at 8:42 AM UTC
- Added a new
POST /campaigns/{campaignId}/auto-select-productsendpoint that automatically selects products and allocates budget for performance campaigns using AI-driven scoring, returning selected products, budget context, and a rationale explaining the selection strategy. - API fields across campaigns, discovery, syndication, and catalog endpoints have been standardized to camelCase (e.g.,
bid_price→bidPrice,is_fixed→isFixed,resource_type→resourceType,adcp_agent_ids→adcpAgentIds,publisher_domain→publisherDomain). Update any requests and response parsing that reference the old snake_case field names. - Error responses from API tools now include a
recoveryfield (correctable,transient, orterminal) to help clients determine whether to retry, prompt the user to fix input, or stop. HTTP status codes are also more precise (e.g., 404 for not found, 409 for conflicts, 429 for rate limiting). - Validation error messages throughout the v2 API are now more descriptive and human-readable, making it easier to identify and correct invalid request payloads.
- Fixed a bug where duplicate products could appear in media buy queries.
- Fixed an issue where campaign update requests could incorrectly send conflicting identifier fields simultaneously, which caused update failures.
- Fixed enforcement of operator authentication requirements during agent authorization flows.
2.29.0 — March 19, 2026 at 7:38 PM UTC
- Added a new measurement data endpoint (
POST /advertisers/{advertiserId}/measurement-data/sync) for syncing advertiser performance data as time-series events, supporting upsert semantics with up to 1,000 measurements per request. - Added property list management endpoints (
/advertisers/{advertiserId}/property-lists) for curating include/exclude lists of publisher domains that automatically apply to all campaigns under an advertiser. - Added a domain validation endpoint (
POST /property-lists/check) that checks domains against the AAO Community Registry, identifying blocked domains, normalizing URLs, and flagging unknowns. - Added storefront management endpoints (
/partner/storefronts) enabling partners to create and configure storefronts with inventory sources and an agent lifecycle, replacing the previous partner/agent registration flow. - Added SCD Type 2 versioning for media buys — updating an active media buy now creates a
PENDING_APPROVALversion; the original remains active until the publisher approves the change. - Added a
debugparameter to the product discovery endpoints (POST /discovery/discover-productsandGET /discovery/{id}/discover-products) that returns detailed per-agent request/response logs when set totrue. - Added support for multiple credential sets per sales agent — customers can now register more than one set of credentials for the same agent, with a
credentialIdparameter on the account discovery endpoint to specify which credential to use. - Added multi-account support with endpoints to list accounts (
GET /buyer/accounts), get the current account (GET /buyer/accounts/current), and switch between accounts (POST /buyer/accounts/switch). - The sales agent list endpoint now returns a maximum of 10 results per page and includes a
nextOffsetfield in the response for easier pagination. - Fixed an issue where child accounts incorrectly required users to accept terms of service when the parent account had already accepted.
- Fixed media buy budget calculations in v1 to correctly sum all products and round spend values.
- Fixed a sync failure that occurred after media buy versioning where associated packages could not be found.
- Removed partner CRUD endpoints (
GET/POST/PUT/DELETE /partner/partners) from the v2 API; partner management is now handled through the storefront onboarding flow.
2.28.0 — March 18, 2026 at 8:11 PM UTC
- Campaigns now support an optional
catalogIdfield on both create (POST) and update (PUT) requests, allowing you to attach a catalog to a campaign. Passnullto detach an existing catalog. - The signal
keyTypeenum has been updated:liverampis renamed torampid, and three new values are added —uid2,euid, andpairid. - Parent customer accounts are now restricted from accessing most REST API endpoints directly. Affected requests will receive a
403 PARENT_ACCOUNT_RESTRICTEDerror. Switch to a child account to regain access. - When connecting an MCP client, users with an existing valid session are no longer shown a redundant login page — they are redirected directly to the callback, preventing duplicate browser tabs from opening.
- Media buys are now automatically transitioned to
COMPLETEDstatus once their end time has passed, keeping campaign and media buy statuses consistent without manual intervention. - Fixed an issue where switching customer accounts in an MCP session did not correctly update permission checks for the new account’s type.
- Fixed a bug where the MCP connector flow could display multiple OAuth pages during authentication.
- Resolved an issue where signals were being polled for media buys that had already passed their end time.
2.27.0 — March 13, 2026 at 9:49 PM UTC
- Added support for partner seats when creating organization-level API keys, allowing users to select both advertiser and partner seats with appropriate type disambiguation
- Enhanced audience sync processing to integrate with real-time syndication services, improving audience delivery performance
- Fixed dependency issues with Google Cloud services to ensure reliable BigQuery and Secret Manager operations
2.26.0 — March 13, 2026 at 6:06 PM UTC
- Added multi-currency support in product pricing displays, now showing proper currency symbols (€, £, ¥) based on product currency instead of defaulting to USD
- Added SSO configuration page for admin users to self-service setup single sign-on with their identity providers
- Fixed discovery endpoint performance issues that could cause timeouts during product searches
- Fixed data accuracy issues in V2 reporting by removing duplicate entries that could inflate metrics
- Improved load balancer timeout handling by increasing from 2 minutes to 4 minutes for better reliability
- Enhanced discovery session lookups by removing redundant filters that could slow down searches
2.25.0 — March 12, 2026 at 6:04 PM UTC
- Added advertiser name field to query responses for better identification and filtering
- Fixed media buy creation process to ensure proper validation order and prevent errors
- Improved authentication to support additional Google Cloud Platform credential types
- Fixed API response format to remove unnecessary internal fields and ensure consistent parameter forwarding
- Updated service token creation to allow organization-level tokens without requiring individual user assignment
- Improved credential management system with enhanced security and updated terminology
- Increased API timeout limits to reduce connection errors and improve reliability
- Enhanced deployment stability with longer grace periods for service updates
2.24.0 — March 12, 2026 at 5:20 PM UTC
- Added advertiser name to ADCP queries for improved query context and results
- Fixed service token creation for organization-level tokens to work without requiring a specific user ID
- Updated API response terminology from “credential registration” to “account linking” for better clarity
- Removed deprecated accountResolution field from API responses to streamline data structure
- Fixed query parameter forwarding for MCP queries to ensure proper request handling
- Increased API timeout limits to prevent request interruptions and improve reliability
- Updated API response format to v2 specification for consistency across endpoints
2.23.0 — March 11, 2026 at 8:16 PM UTC
- Added campaign audience targeting functionality to campaigns API - allows targeting and suppressing specific audiences when creating or updating campaigns
- Added timeframe selection controls to reporting metrics - users can now select custom date ranges and preset timeframes (7 days, 14 days, 30 days, all time) when viewing campaign performance data
- Added new suggestion history tracking table to store campaign suggestion status and transitions
- Fixed signal creation tool to make agent ID and access parameters optional for more flexible signal registration
- Fixed issue where certain table formatting was incorrectly triggering interactive UI detection
- Fixed Docker builds by properly scoping gitignore patterns for output directories
- Improved authentication model to enforce stricter security checks across customer boundaries
2.22.1 — March 11, 2026 at 1:43 AM UTC
- Temporarily disabled webhook signature verification to resolve compatibility issues with upstream client libraries
- Fixed linkedAccounts field to return an empty array instead of undefined when includeAccounts=true is specified but no accounts exist
- Improved CSV export reliability by using a dedicated storage bucket for report downloads
- Fixed reporting data lookups to use the correct media buy identifiers for more accurate BigQuery results
- Removed creative sets endpoints from the API specification
2.22.0 — March 10, 2026 at 11:48 PM UTC
- Added push notification configuration support to the audience sync API endpoint to enable real-time updates when sync operations complete.
- Fixed advertiser list responses to properly return the
advertiserIdfield instead of incorrect field mapping. - Enhanced observability functions to handle edge cases more gracefully and prevent potential API errors.
2.21.0 — March 10, 2026 at 7:02 PM UTC
- Added signal groups for audiences, allowing you to organize and manage multiple signals together for better audience targeting
- Added optimization apply mode setting that controls whether AI model optimizations to media buys are applied automatically or require manual approval - can be set at advertiser level (default for all campaigns) or overridden per campaign
- Fixed text formatting issues in sales agent and advertiser list responses to ensure all account status, credential requirements, and linked account information is properly displayed
- Improved production deployment reliability by fixing Docker build issues that could occur during retry scenarios
2.20.0 — March 10, 2026 at 4:56 PM UTC
- Added
sandboxfield to media buy API responses to indicate when a media buy belongs to a sandbox advertiser - Moved audience management endpoints from separate “Audiences” tag to “Advertisers” tag in API documentation for better organization
- Fixed button text readability issues in dark mode across the UI
- Added enriched brand preview functionality when creating or editing advertisers with unregistered domains
- Increased API timeout from 30 seconds to 3 minutes for acceptance tests to handle longer-running operations
- Improved production deployment reliability by fixing retry scenario handling
2.19.0 — March 10, 2026 at 3:37 AM UTC
- Added comprehensive product detail view showing detailed manifest information including formats, reporting capabilities, optimization goals, setup requirements, and targeting approach
- Added publisher domain filter to product discovery allowing filtering of products by specific publisher domains
- Added audience syndication endpoint to distribute audiences to sales agents with status tracking
- Implemented audience syndication status query endpoint with filtering by resource type, status, agent, and other parameters
- Added product detail endpoint for retrieving full product specifications and manifest data
- Enhanced product descriptions with formatted display showing bold labels for structured information
- Fixed cross-sandbox linking prevention to ensure data isolation between different sandbox environments
- Improved product discovery service integration for more reliable product recommendations
- Enhanced UI formatting for better readability of product information and descriptions
2.18.0 — March 9, 2026 at 8:48 PM UTC
- Added
pricingModelfilter to product discovery endpoints to filter inventory by pricing type (cpm, vcpm, cpc, cpcv, cpv, cpp, flat_rate) - Added
sandboxparameter to advertiser creation for testing campaigns without real spend - all operations for sandbox advertisers use test accounts - Added
sandboxquery parameter to advertiser listing to filter by sandbox/production advertisers - Enhanced product discovery UI to support multiple pricing options per product with interactive price selection
- Fixed OAuth credential storage to prevent cross-customer account linking security issue
- Fixed malformed JSON responses from AI services that could cause discovery failures
- Improved streaming connection reliability for real-time updates with automatic resumption on disconnect
- Fixed budget field conversion issues that could cause campaign creation errors
2.17.1 — March 6, 2026 at 9:47 PM UTC
- Renamed
bundleIdtodiscoveryIdacross all API endpoints for better terminology clarity - Updated
/api/v2/buyer/bundles/*endpoints to/api/v2/buyer/discovery/*to reflect the product discovery workflow - Campaign creation and updates now use
discoveryIdinstead ofbundleIdto reference product selections - All API responses now return
discoveryIdinstead ofbundleIdfor consistency - Updated product selection workflow terminology from “bundle” to “discovery session” throughout the API
2.17.0 — March 6, 2026 at 8:03 PM UTC
- Added multi-provider AI service with automatic fallback and circuit breaker protection for improved reliability and faster response times
- Added new notification event types for optimization suggestions (received, approved, rejected, applied, failed)
- Fixed product discovery view to display actual pricing models (CPM, vCPM, CPC, etc.) instead of hardcoded “CPM” labels
- Fixed pricing consistency issues in product recommendations by including pricing options in product data
- Improved bundle descriptions by deprioritizing pricing information to focus on key features
- Enhanced customer domain handling by using database values instead of deriving from email addresses
2.16.0 — March 6, 2026 at 6:59 PM UTC
- Multi-provider AI service with automatic failover for improved reliability and reduced downtime when generating content
- Added new optimization suggestion notification event types for campaign optimization workflows
- Fixed pricing model display in product discovery to show actual model (vCPM, CPC, etc.) instead of always showing “CPM”
- Fixed pricing options data consistency in product listings and API responses
- Improved pricing display logic to show appropriate labels based on actual product pricing models
- Enhanced bundle descriptions by reducing emphasis on pricing information for better readability
- Fixed customer domain resolution to use database values instead of deriving from email addresses
2.15.0 — March 6, 2026 at 12:46 AM UTC
- New audience management endpoints: sync CRM audiences with hashed identifiers, list stored audiences, and track processing status
- New task status endpoint to poll async operation progress when webhooks aren’t available
- New notification system with endpoints to list, mark as read, and acknowledge notifications about campaigns, agents, and other resources
- New contract information endpoint for platform admins to view contract details
- New user invitation management for admins: approve, reject, resend, or cancel pending invitations
- Enhanced product discovery with AI-generated “why” explanations for recommended media plans
- Bundle management now supports replacing all products instead of just adding new ones
- Bundle apply-proposal endpoint to automatically add products from recommended plans with budget allocations
- Interactive product selection UI improvements with better handling of existing bundle products and confirmation flows
- Added parent-child customer hierarchy support allowing parent account users to access child accounts via header
- Sales agent status transitions now properly enforced - disabled agents cannot be updated
- Fixed campaign budget calculations to exclude archived media buys
- Fixed sales agent manifest resolution during campaign execution
- User access request flow for existing organizations when invitation system is enabled
- Enhanced MCP session management with cross-pod synchronization and better impersonation persistence
2.14.0 — March 5, 2026 at 11:15 PM UTC
- Added new audience management endpoints for syncing first-party CRM data with hashed customer identifiers for targeting
- Added notification system with endpoints to list, mark as read, and acknowledge notifications about campaigns, agents, and other resources
- Added task polling endpoints to check status of asynchronous operations like audience syncing and media buy creation
- Added contract information endpoint for admin users to view their organization’s contract details
- Added parent-child customer hierarchy support allowing parent users to access child organization data via header
- Added user invitation system with request access flow for existing organizations
- Added bundle proposal application endpoint to automatically apply recommended media plans with budget allocations
- Enhanced bundle product selection to support replace mode instead of just adding products
- Enhanced product discovery with AI-generated explanations for recommended plan allocations and budget guidance
- Enhanced signup flow to require invitations for joining existing organizations when enabled
- Fixed campaign budget calculations to properly exclude archived media buys
- Fixed media buy retrieval to work without seat filtering restrictions
- Fixed brief updates in product discovery to show current information
- Fixed cross-pod session synchronization to prevent stale data when switching between servers
2.13.0 — March 5, 2026 at 4:40 PM UTC
- Added new audience management endpoints for syncing first-party customer data with hashed identifiers
- Added new notification system with endpoints to list, mark as read, and acknowledge system notifications
- Added contract information endpoint for admin users to view agreement details and status
- Added task status endpoint for tracking asynchronous operations like audience syncing
- Added LLM-enhanced recommendation logic that provides detailed rationale for suggested media plans
- Fixed media buy retrieval to work properly without seat-based filtering
- Fixed campaign budget calculations to exclude archived media buys from active budget totals
- Fixed brief updates in product discovery to work more reliably
- Fixed audience data type handling to properly support large seat ID values
2.12.0 — March 4, 2026 at 9:41 PM UTC
- Enhanced media buy creation and updates to automatically extend campaign end dates when media buy end times exceed the campaign timeline
- Added start_time and end_time fields to media buy responses, allowing independent scheduling within campaign bounds
- Improved webhook signature validation to return 401 errors instead of 500 errors for authentication failures
- Fixed session state persistence issues that could cause seat selection and customer switching to fail silently
- Enhanced brand agent ID validation in API tools to provide clearer error messages when invalid IDs are provided
- Improved error handling for session state changes to ensure consistency between local and stored state
2.11.0 — March 4, 2026 at 7:59 PM UTC
- Added support for media buy-level start and end dates that can be set independently from campaign dates
- Media buy end dates that exceed campaign end dates will now automatically extend the campaign end date
- Enhanced webhook security with HMAC signature verification for improved request authentication
- Fixed webhook signature validation errors that were previously returning HTTP 500 instead of HTTP 401
- Fixed session state persistence issues that could cause seat and customer switches to fail silently
- Improved brand agent ID validation to require numeric values and provide clearer error messages when invalid IDs are used
2.10.0 — March 4, 2026 at 1:12 AM UTC
- Added new
POST /api/v2/buyer/advertisers/{advertiserId}/event-sources/syncendpoint for bulk syncing event sources with upsert functionality - Fixed OAuth redirect URI validation to support dynamic query parameters for Microsoft Copilot Studio integrations
- Resolved build warnings in the user interface that could affect page loading performance
2.9.0 — March 3, 2026 at 11:14 PM UTC
- Added Microsoft Copilot OAuth support with OpenID Connect discovery endpoint for seamless integration
- Fixed UI v2 flag to automatically grant app access, simplifying feature flag management
- Improved MCP session reconnection reliability by preserving session state across API deployments
- Fixed authentication credential lookup to use the correct database table for improved connection stability
2.8.0 — March 3, 2026 at 4:46 PM UTC
- Improved error reporting when media buy submissions fail - you’ll now receive more specific error messages to help diagnose issues
- Streamlined seat management by consolidating description storage, improving performance for advertiser and partner operations
- Fixed automatic installation of pre-archive hooks during workspace setup to ensure proper workflow execution
2.7.0 — March 3, 2026 at 5:52 AM UTC
- Catalog sync and listing endpoints moved to new paths:
POST /api/v2/buyer/advertisers/{advertiserId}/catalogs/syncandGET /api/v2/buyer/advertisers/{advertiserId}/catalogs(replacing previous/sync_catalogsand/list_catalogsendpoints) - Account linking now supports soft-delete functionality to preserve historical account assignments for better media buy attribution
- Improved account resolution logic ensures more reliable account identification across different sales agent configurations
- Fixed account assignment workflow to properly handle account reassignment scenarios when advertisers switch to new accounts
- Enhanced catalog sync validation to ensure advertiser ID consistency between URL path and request body
- Improved database query performance and reliability for account-related operations
2.6.0 — March 2, 2026 at 10:07 PM UTC
- Added new endpoint
POST /api/v2/advertisers/:id/restoreto restore archived advertisers (admin users only) - Added support for filtering advertisers by status with new
ALLoption to retrieve both active and archived advertisers - Fixed webhook processing to maintain backward compatibility with legacy systems that don’t include HMAC signature headers
2.5.0 — March 2, 2026 at 5:56 PM UTC
- Added new catalog management endpoints for syncing and listing product catalogs via
/api/v2/buyer/sync_catalogsand/api/v2/buyer/list_catalogs - Added comprehensive account linking workflow for advertisers with new endpoints to discover and link partner platform accounts
- Added new
/api/v2/buyer/sales-agents/accountCredentialsendpoint to list all registered sales agent credentials - Enhanced advertiser creation and updates to support linking partner accounts at creation time
- Added
includeAccountsparameter to advertiser list endpoint to embed linked partner account information - Fixed JSON response formatting for AI assistants to use proper structured output mode
- Added new
urlvalue to signal key types for expanded targeting capabilities - Enhanced platform monitoring with comprehensive metrics, dashboards, and alerting for better service visibility
2.4.0 — February 27, 2026 at 4:23 AM UTC
- Fixed an issue where default channels and country codes were being automatically injected into product discovery requests, ensuring that empty channel and country filters are now respected as intended.
2.3.1 — February 27, 2026 at 12:56 AM UTC
- Performance campaigns now support multiple optimization goals with priority ordering, allowing more sophisticated targeting strategies
- Event-based optimization goals now support multiple event sources and improved targeting options including maximize value and threshold rate targets
- Metric-based optimization goals introduced for optimizing seller-native delivery metrics like clicks, views, and engagement
- Fixed issue where production deployment notifications were not properly marked as skipped for staging-only releases
- Fixed version bumping process to correctly include all application components during production releases
- Improved campaign execution workflow to properly handle new optimization goal structure
2.3.0 — February 26, 2026 at 9:54 PM UTC
- Added new event source validation that enforces valid IAB ECAPI event types at the database level
- Added organization-level API key management with role-based permissions and advertiser scoping
- Enhanced service token API to support revealing token secrets via
includeSecretquery parameter - Improved partner and advertiser management UI with updated styling and navigation
- Fixed changelog display by replacing accordion layout with plain bullet lists for better readability
- Enhanced OAuth token refresh flow with better error tracking and logging for MCP clients
- Improved Stripe billing portal session creation with better customer ID persistence and deduplication
- Fixed product discovery to work correctly even when campaign briefs are not provided
- Enhanced service token creation and management workflows with improved validation and user experience
2.2.0 — February 26, 2026 at 2:16 PM UTC
- Added seat-scoped service tokens with full CRUD support via the V2 REST API
- Added ability to bypass Terms of Service acceptance for customers with custom contracts
- Fixed service token creation to make the name field optional with a sensible default
- Fixed brand agent listing to correctly filter by customer for SuperAdmin users
2.1.5 — February 25, 2026 at 1:18 PM UTC
- Fixed request timeout handling for AI model requests to prevent hanging operations and improve response reliability.
- Resolved an issue where certain aborted AI generation requests would unnecessarily retry, reducing API latency.
- Updated AI model version for more consistent response quality and performance.
2.1.4 — February 25, 2026 at 3:58 AM UTC
- Internal improvements and maintenance
2.1.3 — February 25, 2026 at 1:30 AM UTC
- Improved compatibility with partner integrations by retrying failed requests using an alternative brand identification format
- Improved error detection to correctly identify and handle validation failures during brand identification
2.1.2 — February 24, 2026 at 8:13 PM UTC
- Improved product discovery reliability with automatic fallback when brand identification fails
- Fixed documentation site routing to correctly serve versioned API docs
- Updated advertiser form field naming for consistency
- Updated homepage copy and messaging
2.1.1 — February 24, 2026 at 3:00 AM UTC
- Fixed documentation homepage returning 401 errors and broken routing for v2 API docs
2.1.0 — February 23, 2026 at 11:10 PM UTC
- Added reporting page with hierarchical metrics table for campaign performance visualization
- Fixed budget currency handling to use the actual currency from product pricing options instead of defaulting to USD
- Fixed creative format assignment to ensure each product only receives creatives that match its supported formats
- Added stable versioned documentation URLs with dark mode branding
- Improved metrics grid layout for better responsiveness across different screen sizes