> ## 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.

# Product forecasts and pricing across buyers

> Read each wholesale product's forecast as its source reports it, and what buyers paid for it in the last quarter, with get and search.

Two reads help the agent that answers your buyers' proposal requests, and you,
judge a product before offering it: what its source forecasts it can deliver,
and what buyers have paid for it. Both are reads of your own catalog; buyers
do not see them.

> [!NOTE]
>
> Both reads are in beta for Seller Accounts on the beta profile. Elsewhere a
> product carries no `forecast`, and `include: ["price_paid"]` is refused with
> `FEATURE_NOT_ENABLED`.

## Forecast

Every `wholesale_product` you read with `get` or `search` carries `forecast`:
the product's delivery forecast exactly as its source reports it, in AdCP's own
shape (`DeliveryForecast`: `points`, `method`, `currency` and the rest). Apostra
does not forecast again for a brief's flight or targeting. When the source
reports no forecast, `forecast` is `null`.

## Pricing across buyers

Add `include: ["price_paid"]` to `get(kind: "wholesale_product")` or
`search(kind: "wholesale_product")` to read what buyers paid for each product.
It is summed across buyers and never shows what any one buyer paid.

```json theme={null}
{ "quarter": "2026-Q3", "average": { "amount": 12.5, "currency": "USD" }, "buyerCount": 7 }
```

Or, when the figure is withheld:

```json theme={null}
{ "quarter": "2026-Q3", "suppressed": true, "reason": "too_few_buyers" }
```

How the figure is worked out:

| Rule | What it means |
| - | - |
| One whole quarter | The latest whole calendar quarter (UTC) before today. There is no custom period and no filter below the product. |
| What was delivered | Delivered spend divided by delivered impressions, per thousand, from your own delivery records, net. A buyer's budget never enters it. Each buyer counts by the impressions it bought. |
| Rounded | To the nearest 5% of the product's list price. |
| Enough buyers | At least 5 buyer accounts bought the product in the quarter. Otherwise `reason` is `too_few_buyers`. |
| No dominant buyer | No buyer had more than 30% of the impressions. Otherwise `reason` is `one_buyer_too_large`. |
| Currency | Each day's spend is converted into the list price's currency at that day's rate. A day with no rate is left out of both spend and impressions. |
| Not sandbox | Sandbox buys are left out. |

`pricePaid` is `null` when the product has no CPM or vCPM list price, because
a per-thousand average cannot be compared with any other kind of price.

A buyer counts as having bought a product when its package booked that
product through the product's own inventory source, under the product's own id
or the storefront's id for it. Two sources can use the same product id, so a
buy through one source never counts toward another source's product. Each
day's delivery counts toward the product the package booked on that day, so a
buy that later moves a package to another product keeps its earlier delivery
on the product it was booked under then. A day on which no version of the buy
was live has no booking to count under and is left out.

## Related

* [Seller limits and the buyer rate card](https://docs.apostra.com/v3/seller-limits-and-rate-card.md)
* [Tool reference](https://docs.apostra.com/v3/tool-reference.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.