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

# Seller analytics

> The sellerAnalytics payload Murph returns — win rate, buyer asks, top products, seasonality, recommended negotiation posture, and how that learning is converting.

## Overview

When you ask Murph for seller analytics, Murph can attach a `sellerAnalytics`
payload to the chat response for visual rendering. The payload summarizes your
recent intelligence runs — discovery-run mix, buyer asks, top surfaced
products, and the commercial outcomes attributed to those runs — and turns them
into directional negotiation guidance.

This page is the canonical reference for that payload. Each section below is one
top-level field of `sellerAnalytics`.

## Agent-supplied storefronts

A storefront whose active inventory sources are all external sales agents and
whose Storefront merchandising capabilities are off does not show Apostra
seller analytics. The external sales agent owns product, sales, and delivery
analytics in that mode; showing an empty Apostra rollup would imply that
real upstream activity was missing.

The in-product dashboard instead identifies each connected sales agent by name
and its published endpoint (or says when no endpoint is published) and acts as
a billing and account-management overview.
From there, open **Plan & Billing** to review the account relationship. Product paths are not
separately monetized and there is no Storefront-wide product-path switch. When
the account has merchandising access and a Source has a ready Storefront-built
path, you can add multiple sources, connect supported ad servers, and use
Apostra seller analytics.
If storefront capabilities are managed for your account, the dashboard keeps
this Agent-supplied identity visible and directs you to your account team
instead of offering an upgrade that the storefront cannot apply.

<Note>
  Seller analytics outcome totals use last-touch product-overlap attribution and
  are directional. Seller recommendations are deterministic coaching signals
  derived from the same window — not automated pricing or packaging changes. Your
  [operating instructions](/v2/storefront/operating-instructions/overview) and
  [buyer instructions](/v2/storefront/buyer-instructions/overview) remain
  authoritative over these signals. For audited campaign delivery reporting, use
  the [reporting endpoints](/v2/guides/reporting-overview).
</Note>

## historicalPerformance

`historicalPerformance` summarizes the analytics window into the negotiation
signals the Merchandising Agent can use.

| Field                           | Type           | Description                                                                                                                                         |
| ------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `runCount`                      | integer        | Recent intelligence runs considered                                                                                                                 |
| `bookedRunCount`                | integer        | Runs with at least one attributed booked media buy                                                                                                  |
| `winRate`                       | number         | Share of recent runs that booked, from `0` to `1`                                                                                                   |
| `askRunCount`                   | integer        | Runs with buyer asks, price objections, or packaging asks                                                                                           |
| `askToBookConversionRate`       | number \| null | Share of ask runs that booked, or `null` when no ask runs exist                                                                                     |
| `priceObjectionConversionRate`  | number \| null | Share of price-objection runs that booked, or `null` when none exist                                                                                |
| `packagingAskConversionRate`    | number \| null | Share of packaging-ask runs that booked, or `null` when none exist                                                                                  |
| `averageBookedBudget`           | number \| null | Average booked budget per attributed booked media buy                                                                                               |
| `averageProductsPerRun`         | number         | Average products shown per run                                                                                                                      |
| `averageProductsPerBookedRun`   | number \| null | Average products shown on booked runs                                                                                                               |
| `averageProductsPerUnbookedRun` | number \| null | Average products shown on unbooked runs                                                                                                             |
| `deliveryRate`                  | number \| null | Delivery-report events divided by booked media buys, or `null` when none booked                                                                     |
| `repeatBuyerCount`              | integer        | Buyer identities with at least two runs in the window                                                                                               |
| `recommendedPosture`            | string \| null | Directional negotiation posture: `hold_value`, `value_preserving_compromise`, `tradeoff_ladder`, `direct_fit`, `price_first`, or `wholesale_mirror` |

## strategySignals\[]

`strategySignals[]` turns `historicalPerformance` into deterministic strategy
guidance.

| Field      | Type                              | Description                                                 |
| ---------- | --------------------------------- | ----------------------------------------------------------- |
| `id`       | string                            | Stable signal key within the generated analytics payload    |
| `priority` | `"high"` \| `"medium"` \| `"low"` | Suggested attention level                                   |
| `label`    | string                            | Short display label                                         |
| `detail`   | string                            | Human-readable reason for the signal                        |
| `posture`  | string                            | Suggested negotiation posture                               |
| `evidence` | array                             | Small list of `{ label, value }` metrics backing the signal |

## outcomes

`outcomes` summarizes attributed outcomes across the window.

| Field                   | Type           | Description                                                                                   |
| ----------------------- | -------------- | --------------------------------------------------------------------------------------------- |
| `attributedRunCount`    | integer        | Number of recent runs with at least one attributed outcome event                              |
| `eventCount`            | integer        | Total attributed outcome events                                                               |
| `submittedCount`        | integer        | Media buys submitted for seller approval                                                      |
| `forwardedCount`        | integer        | Media buys forwarded to inventory sources                                                     |
| `forwardFailedCount`    | integer        | Media-buy forward attempts that failed                                                        |
| `rejectedCount`         | integer        | Media buys rejected by the seller                                                             |
| `deliveryReportedCount` | integer        | Delivery report events attributed to recent runs                                              |
| `bookedMediaBuyCount`   | integer        | Unique attributed media buys with a booked budget                                             |
| `bookedBudget`          | number         | Sum of attributed booked budget in the window, counted once per media buy                     |
| `deliveredImpressions`  | integer        | Sum of attributed delivered impressions                                                       |
| `deliveredSpend`        | number         | Sum of attributed delivered spend                                                             |
| `deliveredCurrency`     | string \| null | Delivery spend currency, or `null` when no delivery currency is known or currencies are mixed |

Each item in `runs[]` carries an `outcome` object for that run:

| Field                   | Type           | Description                                                                                                     |
| ----------------------- | -------------- | --------------------------------------------------------------------------------------------------------------- |
| `eventCount`            | integer        | Attributed outcome events for the run                                                                           |
| `latestType`            | string \| null | Latest attributed event type, or `null` when no events are attributed                                           |
| `latestStatus`          | string \| null | Latest media-buy status, or `null` when no status is available                                                  |
| `mediaBuyId`            | string \| null | Latest attributed media-buy ID, or `null` when no media buy is attributed                                       |
| `submittedCount`        | integer        | Media buys submitted for seller approval                                                                        |
| `forwardedCount`        | integer        | Media buys forwarded to inventory sources                                                                       |
| `forwardFailedCount`    | integer        | Media-buy forward attempts that failed                                                                          |
| `rejectedCount`         | integer        | Media buys rejected by the seller                                                                               |
| `deliveryReportedCount` | integer        | Delivery report events attributed to the run                                                                    |
| `bookedMediaBuyCount`   | integer        | Unique attributed media buys with a booked budget                                                               |
| `bookedBudget`          | number \| null | Sum of attributed booked budgets for the run, counted once per media buy, or `null` when no budget is available |
| `deliveredImpressions`  | integer        | Delivered impressions attributed to the run                                                                     |
| `deliveredSpend`        | number         | Delivered spend attributed to the run                                                                           |
| `deliveredCurrency`     | string \| null | Delivery spend currency, or `null` when no delivery currency is known or currencies are mixed                   |

`latestType` is one of `media_buy_submitted_for_approval`,
`media_buy_forwarded`, `media_buy_forward_failed`, `media_buy_rejected`, or
`delivery_reported`.

## buyers\[]

`buyers[]` rolls the same window up by buyer identity.

| Field                     | Type           | Description                                                                                   |
| ------------------------- | -------------- | --------------------------------------------------------------------------------------------- |
| `operatorDomain`          | string \| null | Buyer operator domain when known                                                              |
| `brandDomain`             | string \| null | Buyer brand domain when known                                                                 |
| `country`                 | string \| null | Buyer country when known                                                                      |
| `firstRunAt`              | string \| null | Earliest run timestamp for this buyer in the window                                           |
| `lastRunAt`               | string \| null | Latest run timestamp for this buyer in the window                                             |
| `runCount`                | integer        | Recent intelligence runs for this buyer identity                                              |
| `bookedRunCount`          | integer        | Runs for this buyer with at least one attributed booked media buy                             |
| `winRate`                 | number         | Share of this buyer's recent runs that booked, from `0` to `1`                                |
| `askRunCount`             | integer        | Runs for this buyer with buyer asks, price objections, or packaging asks                      |
| `askToBookConversionRate` | number \| null | Share of this buyer's ask runs that booked, or `null` when no ask runs exist                  |
| `attributedRunCount`      | integer        | Runs with at least one attributed outcome event                                               |
| `eventCount`              | integer        | Attributed outcome events for this buyer identity                                             |
| `totalShownProducts`      | integer        | Products shown across the buyer's runs                                                        |
| `averageShownProducts`    | number         | Average products shown per run                                                                |
| `priceObjectionCount`     | integer        | Runs with detected price objections                                                           |
| `packagingAskCount`       | integer        | Runs with detected packaging asks                                                             |
| `requestAskCount`         | integer        | Buyer request-level asks detected in the window                                               |
| `productAskCount`         | integer        | Product-level asks detected in the window                                                     |
| `proposalAskCount`        | integer        | Proposal-level asks detected in the window                                                    |
| `bookedMediaBuyCount`     | integer        | Unique attributed media buys with a booked budget                                             |
| `bookedBudget`            | number         | Sum of attributed booked budget for this buyer identity                                       |
| `averageBookedBudget`     | number \| null | Average booked budget for this buyer's attributed booked media buys                           |
| `deliveredImpressions`    | integer        | Delivered impressions attributed to this buyer identity                                       |
| `deliveredSpend`          | number         | Delivered spend attributed to this buyer identity                                             |
| `deliveredCurrency`       | string \| null | Delivery spend currency, or `null` when no delivery currency is known or currencies are mixed |
| `recommendedPosture`      | string \| null | Buyer-specific directional negotiation posture                                                |

## seasonality\[]

`seasonality[]` buckets the same window by UTC month.

| Field                     | Type           | Description                                                            |
| ------------------------- | -------------- | ---------------------------------------------------------------------- |
| `period`                  | string         | Month bucket in `YYYY-MM` form                                         |
| `runCount`                | integer        | Intelligence runs in the period                                        |
| `bookedRunCount`          | integer        | Runs in the period with at least one attributed booked media buy       |
| `winRate`                 | number         | Share of period runs that booked, from `0` to `1`                      |
| `askRunCount`             | integer        | Period runs with buyer asks, price objections, or packaging asks       |
| `askToBookConversionRate` | number \| null | Share of period ask runs that booked, or `null` when no ask runs exist |
| `priceObjectionCount`     | integer        | Period runs with detected price objections                             |
| `packagingAskCount`       | integer        | Period runs with detected packaging asks                               |
| `bookedBudget`            | number         | Sum of attributed booked budget in the period                          |
| `averageBookedBudget`     | number \| null | Average booked budget across booked runs in the period                 |
| `averageShownProducts`    | number         | Average products shown per run in the period                           |
| `recommendedPosture`      | string \| null | Directional posture inferred for the period                            |

## postureConversion

`postureConversion` is the learning readout: which negotiation posture your
Merchandising Agent actually used is booking deals, and whether following the
history-derived recommendation booked better than diverging from it. It is the
proof behind the `recommendedPosture` that appears throughout this payload.

It distinguishes two postures per run: the **selected** posture (what the agent
used this time) and the **recommended** posture (the history-derived suggestion —
the same one documented under `historicalPerformance.recommendedPosture`).

### postureConversion.byPosture\[]

Conversion rolled up by the posture the agent actually used (the `selected`
posture). Runs where no composition ran — and so have no selected posture — are
excluded from every denominator.

| Field            | Type    | Description                                                                                      |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `posture`        | string  | The negotiation posture used (see `historicalPerformance.recommendedPosture` for the six values) |
| `runCount`       | integer | Recent runs that used this posture                                                               |
| `bookedRunCount` | integer | Those runs with at least one attributed booked media buy                                         |
| `winRate`        | number  | Share of this posture's runs that booked, from `0` to `1`                                        |
| `bookedBudget`   | number  | Sum of attributed booked budget for runs using this posture                                      |

### postureConversion.adherence

How often the agent followed its own history-derived recommendation, and whether
following it converted better than diverging from it.

| Field                | Type           | Description                                                                   |
| -------------------- | -------------- | ----------------------------------------------------------------------------- |
| `comparableRunCount` | integer        | Runs where both a selected and a recommended posture are present              |
| `followedCount`      | integer        | Comparable runs where the selected posture matched the recommendation         |
| `followedWinRate`    | number \| null | Share of followed runs that booked, or `null` when there are no followed runs |
| `divergedWinRate`    | number \| null | Share of diverged runs that booked, or `null` when there are no diverged runs |

**How to read it:** when `followedWinRate` is higher than `divergedWinRate`,
following the learned recommendation is converting better — the signal the
learning loop is working. The reverse is a prompt to revisit your
[operating instructions](/v2/storefront/operating-instructions/overview). Both
rates stay `null` until there are enough comparable runs to compare.

## learnedDefault

`learnedDefault` is the negotiation posture your Merchandising Agent has saved as
its own default — the first rule the agent writes for itself. Where
`postureConversion` is the live readout of what is converting, `learnedDefault`
is the persisted rule distilled from it: a durable, visible, revertible default
that survives across sessions.

| Field       | Type           | Description                                                                                                           |
| ----------- | -------------- | --------------------------------------------------------------------------------------------------------------------- |
| `posture`   | string         | The saved default negotiation posture (one of the six values listed under `historicalPerformance.recommendedPosture`) |
| `reason`    | string \| null | Why it was learned — e.g. `"Hold value booked 64% over 14 runs"`, or `"Pinned by you"` when you set it yourself       |
| `checkedAt` | string \| null | ISO 8601 timestamp of when the default was last written                                                               |

`learnedDefault` is `null` until a default has been saved. Two conditions must
both hold before the agent saves one:

1. **A sustained, evidence-gated signal.** A single posture must be both
   converting above the floor and backed by enough recent runs — a one-off win
   never becomes a saved default.
2. **The learning loop is switched on for your storefront.** Saving a default is
   gated and off by default; until it is enabled, the agent reads its posture
   live on every request and saves nothing.

**How it is used:** the agent applies `learnedDefault` only as a *fallback* —
when it has no fresher, buyer-specific read for the request in front of it. It is
never a forcing override. Your
[operating instructions](/v2/storefront/operating-instructions/overview) and any
buyer-specific rules always take precedence, so you stay in control of how your
storefront sells.

**Clearing or pinning it:** you stay in control of the saved default. Ask your
agent to **pin** a specific posture as the default yourself — the saved `reason`
then reads `"Pinned by you"` and the agent will **not** relearn over it, even
while it keeps learning, until you change it. Or ask it to **clear** the default
(revert to agent-managed): the saved default is removed and the agent may learn a
new one from outcomes again. Either way the learned default remains a fallback the
agent uses only when it has no fresher read; pinning or clearing never changes
which postures the agent considers, only which one it falls back to.

## sellerRecommendations\[]

`sellerRecommendations[]` turns those directional signals into seller actions.

| Field      | Type                                                                                                                      | Description                                                                      |
| ---------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `id`       | string                                                                                                                    | Stable recommendation key within the generated analytics payload                 |
| `priority` | `"high"` \| `"medium"` \| `"low"`                                                                                         | Suggested attention level                                                        |
| `kind`     | `"protect_expand"` \| `"prioritize_follow_up"` \| `"packaging_friction"` \| `"price_resistance"` \| `"tighten_selection"` | Recommendation category                                                          |
| `title`    | string                                                                                                                    | Short display title                                                              |
| `detail`   | string                                                                                                                    | Human-readable reason for the recommendation                                     |
| `action`   | string                                                                                                                    | Suggested next seller action                                                     |
| `buyer`    | object \| null                                                                                                            | Buyer identity the recommendation is about, or `null` for global seller guidance |
| `evidence` | array                                                                                                                     | Small list of `{ label, value }` metrics backing the recommendation              |

## Related

<CardGroup cols={2}>
  <Card title="Storefront overview" href="/v2/storefront/overview" icon="store">
    What a storefront is and how its pieces fit together.
  </Card>

  <Card title="Intelligence runs" href="/v2/storefront/intelligence-runs/overview" icon="microscope">
    The per-run records these analytics aggregate.
  </Card>

  <Card title="Ask Murph" href="/v2/setup/ask-murph" icon="sparkles">
    How to ask Murph for analytics in the storefront workspace.
  </Card>

  <Card title="Reporting overview" href="/v2/guides/reporting-overview" icon="chart-bar">
    Audited delivery reporting for finished campaigns.
  </Card>
</CardGroup>
