Skip to main content

Overview

The demand inbox is your storefront’s front-of-house ledger: one place that answers what demand came in, how did my agent respond, and did we win? Each row is one buyer brief your Merchandising Agent answered, joined to the seller response it produced and the commercial result that followed. A response is called a Proposal only when the persisted response carries a proposal id; otherwise returned products are a product offer. It is the human-readable scoreboard on top of your intelligence runs. Every number is computed only from what actually happened. A metric with no inputs yet reads as unavailable — never a fabricated 0. A historical brief captured before canonical artifact persistence reads as artifact unavailable rather than being reconstructed. The Page reads the v3 demand-loop records directly. Its list is search({ "kind": "rfp" }), row drill-in is get({ "kind": "rfp_turn" }), feedback and revisions use save_rfp, and aggregate analytics come from get_rfp_performance. The Page does not call a hidden demand-inbox list endpoint or compute its own analytics rollups.

The metrics strip

The scoreboard covers this year’s briefs and counts your agent’s first response to each brief. Imported briefs are excluded: the scoreboard measures work your agent did in this year, rather than historical work you added for reference. Renegotiation (refine) passes are not yet rolled up to their originating brief, so the win rate reflects first-response briefs rather than the full negotiation. A seller-adjusted revision you Send (see Adjusting a proposal) is never counted here either — composing and sending a revision writes no new brief-response record, only a new pass on the exchange that already exists, so the agent-vs-human split moves but the first-response metrics above cannot be inflated or deflated by your own edits.

The ledger row

Each row carries the brief, advertiser, buying operator, actual response kind, when it came in and went out, response elapsed time when recorded, who led the response (agent or human), the buyer’s feedback, commercial lifecycle, and your letter grade.
  • Result derives from the brief run’s own persisted state. Live demand uses the commercial outcome: a forwarded or delivered buy is closed_won, a rejected buy is closed_lost, and anything still in flight (or not yet attributed) remains undecided. For those live rows, the UI names the most specific state, such as Product offer sent · awaiting advertiser decision, Proposal sent · awaiting advertiser decision, or Media buy submitted · awaiting seller approval. Imported references instead read Imported reference · not sent to a buyer. A non-live row gets a purpose badge: Draft response · not sent to a buyer for draft, Evaluation response · no buyer for evaluation, Practice response · no buyer for practice, Setup test response · no buyer for setup_test, Simulated response · no buyer for simulation, and Probe response · no buyer for probe. A failed or unavailable response keeps its recorded failure state rather than being relabeled by purpose. A booking attributed to a later renegotiation pass is not rolled up here (see the scope note above). There is no separate result to keep in sync — it always reflects the run’s real state.
  • Grade, feedback, and led-by are seller-authored annotations you record against a row. Grade and feedback default to empty; led-by defaults to the agent, since every composed response is agent-led until a human takes it over.

Advertiser, operator, and account identity

The primary commercial identity is the advertiser brand. The buying operator — the organization operating the buy — appears secondarily. Together they form the advertiser relationship described by AI-5080: BrandRef × Operator. A direct buy can therefore show the same organization on both axes; an agency-operated buy keeps the brand and agency distinct. The surface reads these values from the persisted AdCP request first: brand.domain (or account.brand.domain) for the advertiser, account.operator for the buying operator, and optional account.account_id as the buyer-declared account reference. When the request uses an opaque account_id, the Seller authorizes that account before discovery and records the approved relationship’s canonical brand and operator on the compose run; those values fill identity fields the opaque wire reference cannot contain. If a request pairs the account id with a different brand or operator, the Seller rejects it before discovery instead of recording split identity. Other historical compose-run snapshots remain fallback evidence only. Missing values read Advertiser not supplied or Buying operator not supplied — never Unknown, and never a customer display name substituted for a missing brand.
An AdCP account_id is not a CRM record and is not a seller-native ad-server mapping. CRM evidence is optional context; source-native account mappings are execution configuration. Neither is joined into the advertiser name on this surface, so “no CRM evidence,” “no required source mapping,” and “advertiser not supplied” remain three different facts.

Product offer, Proposal, and money

The response label follows the persisted response contract: The budget remains the buyer’s stated range and currency. CPM or another product price remains the selected persisted pricing option and its own currency. A proposed allocation becomes an amount only against a point budget where min === max; an open range or one-sided bound stays percentage-only. Won value comes from delivered spend when recorded, otherwise the booked media-buy budget, and only when amount and currency were persisted together. These figures are never converted or filled from one another.

Where a brief came from

Not every brief arrives as a live AdCP call from a buyer agent. Each row carries its provenance so you always know what you’re looking at: An uploaded brief never masquerades as live buyer demand: no buyer is recorded unless you confirmed the buyer from the document, no buyer is contacted, and nothing is booked. It counts on the scoreboard by the same rules as any other brief — an uploaded brief has no commercial outcome until you record one, so it stays pending and never inflates your win rate.

Uploading a brief into chat

When a brief reaches your sales lead by email or attachment instead of by API, you don’t need a form. Drop the document into the Murph composer. Murph reads it, shows you the demand brief it recognized (unconfirmed), and — if the upload includes a media kit — tells you in chat what the kit claims that your storefront can and can’t back. Nothing is written or run until you confirm. When you confirm, the brief runs through the same product-discovery and composition path a buyer’s agent would trigger, and the exchange appears here as an uploaded row that drills into the proposal pass like any other. To change an uploaded exchange, upload or paste a corrected brief and confirm it — that produces a new exchange. The original keeps its honest record and stays annotatable (grade, feedback, result).

Importing a historical brief

Add a historical RFP when you want a past buyer request and your response to teach the agent. From the Library, add the response, choose the brief it answered, or create the imported brief inline. The record carries origin: imported and appears in this ledger so it can be paired, annotated, and endorsed. It is excluded from Briefs YTD, Answered, and Win rate, because those measures describe live and agent-run demand rather than a reference you added from history.

Attach what we sent

Open a brief and choose Attach what we sent to add the response you sent to the buyer. The response is filed in the Library and paired with this brief. There is no separate link to create. A response without a brief stays in the Library as a standalone shape example, not an evaluation.

Commentary and endorsement

Grade and feedback on a row are the commentary on its brief-response pair. After a response is attached or already present, choose Endorse to mark the pair as the answer you want your agent to learn from. Removing the endorsement leaves the brief, response, commentary, and commercial outcome in place; it only stops that pair from being offered as an endorsed example.

The seller-response pass

Open a ledger row to see the full story of that exchange — the response pass. It answers what exactly did my agent return, from what brief, and how did the exchange evolve? The pass shows:
  • The brief, as a business document. It leads with the advertiser, who it came through, and the buyer’s ask in their own words, then the few facts a commercial decision turns on: budget, flight, markets, channels, how they want to transact, and how long you have to respond. Requirements follow as plain sentences — placements, exclusivity, currencies, policies, the metrics they expect back, performance standards and verification vendors — then where it has to run: regions, metros, an approved property list by name, keywords, and the advertiser catalog. A field the buyer did not send is simply absent; you are never shown a row that says nothing.
  • Condensed brief facts appear only while the complete brief is loading, if its read fails, or for historical rows with no artifact link. They are an honest fallback, never a reconstructed substitute for the request.
  • A composed pitch, when your storefront has one for this pass. The pass opens on a written argument, read as a story: what the buyer’s brief asked for, why you, the plan told as roles instead of rows, proof from a matched case study, the terms, and the ask — before the product table, which moves under a Plan appendix heading beneath it. A pass with no composed pitch renders exactly as it always has: the plan, and nothing invented around it. See The pitch and The story-first proposal.
  • The plan, as the products you sent. The plan’s name, its scale, and its argument for the brief come first, then one line per product with its price and its share of the plan. Expand a product to see why it is in the plan, how it is priced (including every option offered and where the plan’s selection sat against market guidance), where it runs, who it reaches, and what it reports.
  • What fed each decision. Expand a product row to see which of your own ingredients your agent consulted when it built that line: the inventory it selected, the audience it layered on, and the rate-card entries it priced against. Tap one to open the thing that owns it — the source it came from, or your Playbook — change it there, and the pass refreshes. Underneath the table, a second group names what fed the whole response rather than one product: the Playbook version it composed under, and the terms resolved for that buyer. See Where “fed by” comes from.
  • Per-product money appears when the buyer committed a single exact budget — each product’s share of that amount, in the plan view and in the pass history. Against an open range or a lone ceiling/floor you see shares only: a proposal commits to a split, and money arrives when the buy is created.
  • Technical details, one disclosure at the foot of each. Artifact id, schema, digest, source, capture size, run linkage, redactions, truncation evidence, and the exact structured request or response — copyable, and identical to what an agent reads. Both the human view and the exact artifact come from the same immutable capture; there is no separately maintained presentation model.
  • Pass history for every recorded response, with the buyer-facing price and plan allocation per product. Selecting a pass opens its full plan above.
  • A refine-pass timeline and the commercial outcome for the exchange.
Every number on the pass is traceable to a persisted brief/response artifact or outcome record; an input that wasn’t captured reads as unavailable rather than being reconstructed. A capture can also be truncated: the response was recorded but part of it exceeded the storage cap. The pass says which — product rows still render when the response survived and only the per-product snapshots were dropped, and a pass whose response itself wasn’t stored is labeled as a truncated capture, never described as predating capture.

Where “fed by” comes from

“Fed by” answers the question a proposal has to survive: why these products, at these prices? It is a record of what your agent actually consulted while composing, written at the moment it composed. It is not a summary the agent writes about itself afterwards, and it is not reconstructed from the finished proposal. Two things follow from that, and they are the reason you can trust it. It is scoped as honestly as the decision was. Some ingredients are chosen per product — the inventory a line is built from, the audience layered on it, the rate-card entries priced against that exact combination. Those appear on the product row. Others are resolved once for the whole response — the Playbook version in force, and the terms that applied to that buyer. Those appear under the table, labelled as feeding the whole pass. Nothing is promoted from one group to the other to make a row look better-explained than it is. It is history, and history is not rewritten. A chip names the ingredient as it stood when the proposal was composed, including its name at the time. Renaming a rate-card entry later, editing your Playbook, or deleting a source never changes what an earlier pass says fed it. If you tap a chip for something you have since deleted, you are told plainly that it no longer exists — you are never sent to a stand-in for it. That check is exact: removing one product or audience from a source you otherwise kept is enough, and a same-named entry on a different source is never treated as the one that fed the decision. And it only ever says “deleted” when it actually checked and found nothing: if the check itself cannot complete, the chip simply becomes un-tappable rather than telling you something was removed when it may not have been. What each chip names: A few honest limits:
  • A pass that predates this shows no chips. Responses composed before your agent started recording what it consulted have nothing to show, and the row simply does not expand. Nothing is inferred for them.
  • A response you adjusted yourself shows the inventory and audience it composed from, and no rate-card or marketing chips. An adjustment re-resolves your inventory but is priced from the adjustment you declared, so there are no rate-card entries to name; it also composes without your product marketing, so no selling point shaped it and none is named. Both absences are the honest record of what that pass actually consulted, not a gap in the display.
  • Your marketing material feeds composition at the whole-response level. Once you’ve confirmed material into your product marketing, an eligible selling point can shape how products in the response are named or described, and the row’s chips show “Your marketing” alongside the exact selling point consulted. Unlike inventory and audience, this is recorded once per response rather than per product line — the same way Playbook guidance is. The chip opens your product marketing page anchored on that exact selling point, so you can see it with its source and evidence.
  • Some chips name something you cannot open. Inventory reached through another seller’s storefront belongs to them, not to a source of yours, so its chip names what fed the decision without a place to go. Buyer terms are the same: they are shown for context and managed on the buyer. A chip whose owner we momentarily could not look up behaves the same way. None of these is described as deleted, because none of them was.
  • Buyer terms appear only when they actually applied. Terms that matched the buyer but were held back — because the request carried no account, or because the row set neither a discount nor a note — did not shape the response, so they are not listed as having fed it.

Adjusting a proposal

Open a proposal pass and, if the exchange qualifies, you can Adjust it: declare a posture, a price adjustment, and a product-count cap, and re-compose the proposal through your storefront’s real merchandising engine — without leaving the page. This is the same declaration grammar the Merchandising Simulator already taught you in a zero-risk room; Adjust reuses it rather than asking you to learn a second way to describe a change. Adjust is available only on live, retained, adjustable demand. When it isn’t, the button is disabled and names exactly why: A stale page or a direct API call gets the same named reason — never a bare “not found.”

Draft, then Send

Composing an adjustment produces a draft revision. A draft is silent by construction: it holds no proposal artifact and no delivery state, so nothing is visible to the buyer until you send it. Declining the sheet leaves no record at all; discarding a draft leaves only its own terminal audit entry — neither counts against anything you’d notice. When you’re ready, Send routes the revision through the same approval setting you already use for media buys — the campaign-approval capability and its manual/auto dial, relaxed for a buyer you’ve explicitly trusted with per-buyer auto-approve. There is no separate approval system to configure.
  • If your storefront auto-approves (or the buyer is trusted), the send clears immediately.
  • Otherwise it queues for a colleague to approve or reject — and whoever drafted the revision cannot clear their own send. You can always reject or withdraw your own submission (that creates no buyer-visible evidence), but sending it requires a second person. A rejected revision returns to draft, and resubmitting it clears the earlier decision entirely — a revision awaiting a decision never shows a decision that hasn’t actually been made against it.
  • A cleared send becomes a real pass on the exchange, labeled seller-adjusted and attributed to the person who sent it — it renders through the same pass card as everything your agent proposed, never a second layout.
Every exchange has a lifetime limit on how many adjustments it can produce — counted over every revision you’ve ever composed on it, including ones you discarded. Compose-and-discard doesn’t reset the count.

What “sent” actually means to the buyer

Be direct with yourself here: sending a revision does not notify the buyer’s agent. We investigated whether a follow-up proposal could reach the buyer through the existing exchange, and today it can’t — there is no delivery lane for a subsequent proposal, and no honest staging/preview lane either. A sent revision is recorded truthfully: it appears in your pass history as sent, not delivered, and the page says so outright. If you need the buyer to actually see the new terms, you still have to reach them the way you would today — a message, a call, or a fresh brief exchange.

What Adjust doesn’t do

A draft never issues a rate hold and never converts into the buyer’s stated currencies — that’s what an actual buyer-facing response does, and a discardable draft must not create that kind of durable, buyer-facing state. The draft does record the settlement currency and the buyer’s stated currencies as of when you composed it, purely for your own reference.

What counts as one exchange

An exchange is grouped from persisted linkage only: one composition pass and the proposal artifacts recorded against it. Byte-identical or refine briefs are not grouped by their content hash (a hash collides across unrelated pursuits and diverges across refines), and there is no persisted cross-run lineage yet — so a renegotiation is its own ledger row and its own exchange today. Each exchange therefore reads as a single composition pass, disclosed honestly on the pass itself. The exchange-level result follows an explicit rule: won if any pass in the exchange is won; otherwise lost if the most recent decided pass is lost; otherwise pending. With one pass per exchange today this is simply that pass’s outcome.

Money

Each row shows the buyer’s stated budget range exactly as it arrived on the brief (buyers state it in filters.budget_range; when a buyer doesn’t, the column reads absence rather than a guess). A won row also shows the won value — the delivered spend when reporting exists, otherwise the booked media-buy budget — always in the money’s own currency, never converted. The Booked YTD tile totals this year’s won money per currency; multiple currencies are disclosed rather than summed together. On the proposal pass, the exchange carries a per-currency won value when it won (one entry per currency, never summed across currencies). A lost exchange still surfaces the buyer’s stated budget as lost demand — the size of the opportunity you didn’t close — so a loss is legible, not blank.

Filters

Filter the ledger by buyer from the widget header to focus on one relationship. Sector filtering is not available yet — sector is not captured per brief today.

Intelligence runs

The per-request detail behind each ledger row.

Seller analytics

The aggregate performance view across many runs.