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

# Goal-seeking campaigns

> How a campaign states what it is trying to achieve, how sellers answer on those terms, what a seller can and cannot promise, who counts the result, and how delivery is judged against the goal.

A campaign should be trying to achieve something, and you should be able to
tell whether it did. A goal-seeking campaign states its goal in a form sellers
can price against, keeps what each seller committed to, carries that
commitment onto the booked media buy, and judges delivery against it.

Take a buyer who says "find dog lovers in Slovenia and get them to my online
store, €5,000". Store traffic is how they will know it worked. Their agent
turns that into a goal statement: clicks, at €3 or less per click, counted by
the seller's ad server, from a seller willing to guarantee the price. Sellers
answer on those terms. One guarantees €3 per click and forecasts 1,700 clicks;
one can only aim for €4.50; one does not sell on clicks and passes. The agent
books the first. At the end of the flight the campaign reports 1,740 clicks at
€2.90, which beat the target.

This page explains each part of that loop. The field shapes live on the
[campaign](/v2/object-guides/campaign#optimization-goal-target-strength-performanceconfig)
and [media buy](/v2/buyer/campaigns/media-buys#optimization-goals) guides;
the request flow is in the
[buyer workflows](/v2/setup/v3/buyer-workflows#3-request-proposals-from-eligible-sellers).

## The goal statement

A goal has four parts. You should be able to read all four in one line:
*clicks, at €3 or less, counted by the seller's ad server, guaranteed*.

| Part | What it is | Where it lives |
| - | - | - |
| **Goal** | The thing you are buying: a delivery metric (clicks, completed views, reach), or an event you track (purchase, lead, a custom event). | `performanceConfig.optimizationGoals[]` on the campaign, as a `metric` or `event` goal. |
| **Target** | The number that makes the goal a success: a cost per unit, a minimum rate, a minimum return on ad spend, or "as much as possible". Optional. | A cost or return target is the campaign's `bidding` policy in V3, applied to the primary goal (see [stating a cost or return target](#stating-a-cost-or-return-target)). In V2 it is the goal's `target`. A rate or "as much as possible" target is the goal's `target` in both. |
| **Counted by** | Who produces the number the goal is judged on. Derived from the goal kind, not chosen. | See [Who counts the result](#who-counts-the-result). |
| **Commitment wanted** | Whether you want a seller who guarantees the price per result, one who will try for it, or one who only reports it. | A preference you state to your agent when you set the goal. It is not a field on the campaign and it does not bind a seller; the seller's pricing terms do. |

The first goal in the list is the primary goal. Sellers see the whole ranked
list; commitments and delivery verdicts are judged against the primary goal.

### Stating a cost or return target

A cost per result ("clicks at €3 or less") and a return on ad spend ("4 back
for every 1 spent") are not stated on a goal in V3. They are the campaign's
`bidding` policy, in AdCP 3.2's own shape, and apply to the primary goal:

* `bidding: { cost_per: { amount, strength } }`: the average cost per primary
  goal result, in the campaign currency. `cap` keeps the average at or below
  the amount and accepts less delivery when necessary. `target` aims at the
  amount while balancing volume and spend.
* `bidding: { roas: { value, strength } }`: the return per unit of spend.
  `floor` prefers less delivery to knowingly going below the return.
  `target` aims at the return. The primary goal must be an event goal whose
  every event source names its `valueField`.

`strength` is required, and a campaign carries one of the two, never both.
A primary goal that already has a rate or "as much as possible" target cannot
also take a policy. A goal holds one target, so the save is refused and asks
you to keep one.
Neither strength is a guarantee per result. What a seller commits to is in its
answer to your goal (see [what a seller can promise](#what-a-seller-can-promise)).
`bidding: null` clears the policy. Reading campaigns with V3 `get` or
`search` returns each campaign's `bidding`, including a target set through V2,
with a missing strength read as `cap` for a cost and `target` for a return.

`save_campaign` refuses a `cost_per` or `per_ad_spend` target on any goal, and
the refusal names `bidding`. In V2,
`performanceConfig.optimizationGoals[].target` still takes those targets with
an optional `strength`. A campaign written either way reads back the same: in
V2 the policy shows as the primary goal's `target`.

A V2 campaign can carry a cost or return target on a goal other than the
primary one, which V3 cannot state. V3 leaves that target alone when a save
sends the same goal back unchanged. When a save removes or changes that
goal, the target is removed and the response names it.

## Who counts the result

Every goal is counted by exactly one party. Choosing a goal chooses who counts
it, and each choice needs something different from you.

| Goal kind | Counted by | What it needs from you | What it can promise |
| - | - | - | - |
| Metric goal (`clicks`, `completed_views`, `reach`, ...) | The seller's ad server. The seller reports the number and can be held to it. | Nothing beyond the goal. | A seller can guarantee a price per unit, because it measures the unit itself. |
| Event goal (`purchase`, `lead`, `custom`) | Your event source: a pixel, a server-side tracker, or an imported conversion feed, with an attribution window. | An [event source](/v2/buyer/event-sources/tasks/index) on the advertiser, and the attribution window you want applied. | A seller can price against your events only if it can read them back; otherwise it optimises toward the event and reports what it sees. |
| Vendor-measured goal (store visits by a measurement vendor, brand lift by a panel) | The measurement vendor. | A measurement source that names the vendor. | Planned, not yet a goal kind. Today, state a vendor-measured outcome in the campaign brief so sellers can read it; the platform does not send it as a structured goal or judge delivery against it. |

Sellers never see your event source id, tracker configuration, or the names of
your custom events. An event goal reaches a seller as its event type (for
example `purchase`) and value field only.

## What sellers see

When you [request proposals](/v2/setup/v3/buyer-workflows#3-request-proposals-from-eligible-sellers),
every solicited seller receives the same brief. Alongside the flight,
geography, channels, formats and audience requirements, the brief carries a
goals section: for each goal, its kind, metric or event type, target, priority
and attribution window. A seller reads a line such as "clicks, target cost
3.00 or less per click in the buy currency, counted by the seller's delivery
metrics" and prices against it.

A seller that receives the canonical AdCP 3.2 `request_proposals` call can also
receive the primary goal in structured form, as `criteria.outcome_target`. It
gets one only when it declares `media_buy.outcome_target` and its
`features.bidding_policy` accepts a media-buy `cost_per` cap. The target names
the goal's metric and its cost per result as `cost_per` with an amount, the buy
currency and `strength: cap`. It carries no volume. The primary goal qualifies
when it has a cost target and is a delivery metric the outcome target can name
(clicks, views, completed views without a view duration, engagements, follows,
saves, profile visits or reach) with no attribution window. Every other goal
travels in the brief only. The seller answers the cost it can plan to in its
proposal's terms (see [best effort](#what-a-seller-can-promise)).

The campaign budget stays withheld. The platform never turns a cost target
into a volume for sellers (budget divided by cost per click), because that
would hand every seller the budget. Sellers quote a price and forecast a
volume; you decide how much of the budget to place with each.

## Which goals a seller's packages carry

The brief tells every seller about every goal. The media buy is stricter: each
package sent to a seller carries only the optimization goals that the
package's product says it can optimize. AdCP products declare this in
`metric_optimization` (metrics the seller measures, and the target kinds it
accepts), `conversion_tracking` (conversion-event goals),
`vendor_metric_optimization` (a measurement vendor's metric) and
`max_optimization_goals` (how many goals one package accepts). Some sellers
reject a whole package that carries a goal they did not declare, so sending
that goal would stop the buy rather than being ignored.

* A goal the product does not declare (its kind, metric, target kind, reach
  unit, view duration, viewability standard or vendor metric) is left off that
  product's package.
* When the product accepts fewer goals than you set, the highest-priority
  goals are sent: priority 1 first, then the order you listed them.
* A product that declares no optimization capability at all receives no
  goals: AdCP ties support for each goal kind to its declaration, so a product
  with none can optimize to none. The seller still sees every goal in the
  brief, and you can still buy the product; it just isn't asked to optimize.

Goals left off a package are reported when the campaign executes. The execute
response carries an `optimization_goals_dropped` warning for each affected
media buy, naming the product, the goal and why it was not sent. The campaign
keeps the goal, and other products that declare it still receive it.

### How a package carries a cost or return target

AdCP 3.2 moves a cost or return target off the goal and into the package's
`bidding` policy, bound to the package's primary goal. A seller receives that
shape when it declares, in `features.bidding_policy.package.fixed`, the mode
(`cost_per` or `roas`) and the strength the target needs. The package's primary
goal then has no `target`, and the package carries `bidding.cost_per` (an
`amount` and a `strength`) or `bidding.roas` (a `value` and a `strength`). The
amount is the target you set.

A cost target with no `strength` is sent as `cap`: the seller keeps the average
cost at or below the amount and delivers less if it has to. A return target
with no `strength` is sent as `target`.

Every other seller receives the target on the goal, as before. A package also
keeps the target on the goal when it carries a bid price, or when a goal other
than its primary goal has a cost or return target, because AdCP does not allow
the two shapes on one package and the policy can express only the primary
goal's target.

## Seeing it before you book

You do not have to wait for execute to find out. The same declaration, read
with the same rule, tells you before booking which goals a product cannot
optimize to:

* Each [proposal's goal answers](/v2/setup/v3/buyer-workflows#read-what-a-seller-committed-to)
  and each proposal-less product returned by `request_proposals` carry a
  `goalCoverage`: whether the product can optimize to your primary goal, and
  each goal it cannot optimize to, by priority, with the reason code.
* [Auto-select](/v2/buyer/campaigns/tasks/auto-select-products) carries the
  same coverage on every product it selects.

A product that declares no optimization capability, or whose declaration does
not match the AdCP schema, shows every goal as one it cannot optimize to, the
same goals execute would leave off its package.

### Expected performance against your goal

When your primary goal is on viewability or video completion and has a
target, `goalCoverage.expected` also says what the product's inventory is
expected to deliver, read from the ranges in the seller's forecast. For
example, "expected 78%-88% viewable vs your 70%".

| Your primary goal | What `low`/`mid`/`high` measure (`basis`) | What `required` is |
| - | - | - |
| `views` or `viewable_rate` with a `threshold_rate` | Viewable ÷ measurable impressions (`viewable_rate`) | Your target rate |
| `views` with a `cost_per` | Viewable ÷ all impressions (`viewable_per_impression`) | The rate your cost per viewable impression needs at the product's CPM: CPM ÷ (1000 × target) |
| `completed_views` with a `threshold_rate` | Completed views ÷ impressions (`completion_rate`) | Your target rate |
| `completed_views` with a `cost_per` | Completed views ÷ impressions (`completion_rate`) | The rate your cost per completed view needs at the product's CPM: CPM ÷ (1000 × target) |

The `verdict` is `likely` when even the low end meets the required rate,
`possible` when only the expected or high end does, and `unlikely` when the
high end misses. Rates run from 0 to 1.

There is no expectation when the goal has no target, the seller's forecast
has no range for the rate, or a cost goal has no CPM price in your campaign's
currency to judge it at (a CPM in another currency is never compared with your
target). A
cost per viewable impression also needs the forecast to say how many
impressions were measured, because unmeasured impressions are paid for but
never count as viewable. Click goals never get one: click-through rates differ
too much between advertisers and creatives for a seller's history to predict
yours. The forecast describes the inventory before the seller optimizes toward
your goal, so treat the verdict as a conservative read.

A seller whose products cannot optimize to your goal still receives the brief,
and you can still book them. Auto-select prefers products that can: it puts
every product that can optimize to your primary goal ahead of every product
that cannot. Among the products that can, it puts `likely` first, then
`possible`, then products with no expectation, then `unlikely`, and keeps its
usual order (historical score, or lowest CPM) within each group. A product that cannot optimize to the goal is chosen only
once the budget reaches past every product that can. It is booked without the
goals it cannot take, and its commitment is `report_only` unless its price is
on the outcome itself.

## What a seller can promise

AdCP is explicit about liability: a seller's bid target is "not a per-result
guarantee". The guarantee, when there is one, is the **price**. A seller that
sells a fixed price per click on a guaranteed product is on the hook for that
price. A seller that sells impressions and promises to aim for €3 per click is
trying.

The platform reads each proposal's commercial terms and labels every
allocation with one of three commitment kinds.

| Commitment | What the seller is saying | Who carries the risk | How it is read off the terms |
| - | - | - | - |
| `guaranteed` | "You pay this much per result, and I make it good if I fall short." | The seller. If results come in under forecast you pay for what was delivered at the agreed price; if the seller cannot deliver, its makegood policy applies. | A fixed price on the outcome itself (`cpc`, `cpa`, `cpcv`, `cpv`) on a guaranteed product, or with a makegood policy in the measurement terms. |
| `best_effort` | "I will aim for this number." | You. The seller optimises toward the target and reports against it, but you pay for exposure (or an outcome price with no guarantee) whether or not the target is met. | An outcome price without guaranteed delivery or remedies, a seller optimisation goal with a cost-per or return target for your goal, or, from a seller on AdCP 3.2, the average cost it plans to for your goal (its `commercial_terms.bidding.cost_per`), which may be higher than your ask. |
| `report_only` | "I will show you the number." | You. Nothing in the terms is tied to your goal. | Exposure pricing (`cpm`, flat rate) with no seller goal for what you asked, or a fixed price on a different outcome. |

Two things follow. A seller's prose ("we are confident in strong click-through
performance") never changes the kind; only terms do. And a proposal is only as
committed as its least committed part: if one allocation is `guaranteed` and
another is `report_only`, the proposal's commitment is `report_only`.

## How proposals answer on the goal's terms

Each quoted proposal carries one goal answer per allocation and a
proposal-level commitment. The answer names the pricing model and fixed price,
the delivery type, the measurement terms, the goal you asked for, the target
the seller's terms actually commit or aim at, and the resulting commitment
kind. The proposal-level summary gives the weakest kind, the worst answered
cost, and whether every allocation meets your asked target.

That lets your agent compare sellers on the goal's terms rather than on price
alone: a guaranteed €3 per click and a best-effort €2.50 per click are
different offers, and the second is not cheaper. Field by field, see
[Read what a seller committed to](/v2/setup/v3/buyer-workflows#read-what-a-seller-committed-to).

A seller that returned no structured answer is labelled as such. The platform
does not guess a commitment from how well the prose aligns with the brief.

## What the booked buy carries

Accepting a proposal books media buys, and each buy carries a
[goal commitment](/v2/buyer/campaigns/media-buys): the goal you
asked, the target the seller answered, the commitment kind, the per-product
answers, and the proposal version they came from. A buy created without a
proposal still gets a commitment from its own terms, so a fixed CPC on a
guaranteed product reads `guaranteed` even if you stated no goal.

The commitment is fixed at booking. A later change to the buy books a new row
with its own commitment, so the record of what was promised when you spent the
money never moves.

## Judging delivery

A campaign with a goal reports two different things, and they answer two
different questions.

**Pacing** answers "is the money moving on schedule?". It compares delivered
spend with how much of the flight has run — not with the budget alone, because
a buy three days into a thirty-day flight that has spent a tenth of its budget
is exactly on pace, while a buy on its last day that has spent the same tenth
is nine tenths undelivered.

**Goal progress** answers "is the campaign achieving what it set out to?". It
compares the number the goal is counted on (clicks, completed views, viewable
rate, leads) against the asked target and the seller's commitment.

The two are reported side by side, because "spend 200 a day at 80% viewable" is
two answers, not one: a buy can be on pace and missing its quality bar, or
hitting its quality bar and underspending. Both read on
[Get reporting metrics](/v2/buyer/reporting/tasks/get-reporting-metrics#goal-progress).

In the Campaigns view, open a campaign to see its goal bar beside pacing, and
again on each media buy. The bar shows what you asked, what the seller
committed to, what has been delivered, and whether the result is on track,
behind, or beat target. A campaign or media buy with no goal and no seller
commitment shows no bar. The view reads goal progress for a campaign's first
100 media buys; for a campaign with more, buys beyond the first 100 show no
bar there. [Get reporting metrics](/v2/buyer/reporting/tasks/get-reporting-metrics#goal-progress)
carries goal progress on every media buy block it returns.

Goal progress is judged on these rules:

* **Achieved, not estimated.** The achieved cost per unit, rate, or volume is
  computed from the same delivery metric the goal names. A missing metric is
  reported as unavailable, never as zero.
* **No verdict without evidence.** A verdict of on track, behind, or beat is
  given only when there are enough observations for the metric to mean
  something. On day one, or when the seller has not yet reported the metric,
  the campaign says why there is no verdict yet instead of guessing. A rate is
  judged on how large the population it divided by was, not on its own count,
  so a low rate over a large, well-measured population is still a real verdict.
* **Basis.** Every number says who counted it: the seller, a measurement
  vendor (with its coverage), or your own event source (with its attribution
  method and window). A seller's click count and your pixel's click count are
  both real and can legitimately differ.
* **Freshness.** Every number says how final it is: the period it covers, the
  measurement window, whether a later window supersedes it, and which metrics
  the seller committed to report but has not yet.

<Note>
  **Viewability goals wait on the seller's counts.** A viewable-rate goal is
  judged from the viewable and measurable impression counts a seller reports
  under AdCP's `viewability` object, and reporting does not read that object
  yet — so a viewable-rate goal reports "not measured" rather than a rate over
  the wrong denominator. The `views` metric is content views, the quantity CPV
  pricing bills on, and is never used as a stand-in for viewable impressions.

  **A measurement-vendor or event-source basis is still planned.** Every number
  today is counted by the seller, and says so.
</Note>

## The seller's record

Once a buy with a commitment completes, the platform keeps what was asked, what
was answered, what was delivered, and whether the seller beat, met or missed its
commitment. It rolls these up per seller, per goal objective (for example
`clicks`, or an event type such as `purchase`) and per commitment kind, because
a kept guarantee and a beaten best effort are different facts. The record covers
completed buys whose delivery was last reported in the past 180 days, judged the
same way as the goal progress you see on your own buys. It also informs how
automatic selection ranks products, for accounts that use product scoring.

Each cell of the record reads:

| Field | Meaning |
| - | - |
| `objective` | What the goal was about, such as `clicks` or `purchase`. |
| `commitment` | The commitment kind: `guaranteed`, `best_effort` or `report_only`. |
| `buys` | Completed buys carrying this commitment, judged or not. |
| `judged` | Buys with enough delivery to be judged. |
| `beat`, `met`, `missed` | How the judged buys came out. |
| `hitRate` | `(met + beat) / judged`, or `null` when nothing has been judged. |
| `medianDelta` | The median distance from target as a fraction of the target. Positive is better than target. `null` when nothing has been judged. |

**Buyers read it on the seller, in the pilot.** Ask for it with
`include: ["commitmentRecord"]` on `search` or `get` with `kind: "seller"`.
Without the include, a seller read is unchanged. The record pools every buyer's
buys with that seller, so a cell is shown only when at least 3 distinct buyers
and at least 5 judged buys stand behind it. Cells with too little evidence are
not shown, which means a seller can have no cell to show yet; that is not the
same as a seller that missed. The record never names a buyer, a campaign or a
media buy, and never says how many buyers stand behind a cell. An account
outside the pilot that asks for it is refused with `FEATURE_NOT_ENABLED`; it is
never handed an empty record that could be mistaken for "no record".

**Sellers see their own record.** A seller asks for the same include on its own
seller read and sees every cell for its own Storefront, without the floor above.
Each input is the seller's own evidence: its answers to goals disclosed to it,
judged on the delivery it reported. It still names no buyer, campaign or media
buy. A seller that can see its record can question it.

<Note>
  **Pilot.** Sellers can read their own record now. Buyer access is limited to
  accounts in the pilot, and widens after sellers have been told what buyers see.
</Note>

## If you do not state a goal

A goal is optional. Without one, sellers price against the brief alone: the
brief they receive carries no goals section. Each proposal still carries goal
answers and a commitment kind read off its terms, but they answer no goal of
yours. The asked goal and `meetsAskedTarget` are empty, and the kind only
says whether the seller priced on an outcome at all (a fixed price per click
on a guaranteed product still reads `guaranteed`). Compare such offers on
price, forecast and fit to the brief.

You can add a goal later. Sellers answer the goals in the brief they
received, so a proposal round requested before the goal existed does not
answer it; request a new round for sellers to answer on the goal's terms.

## Three questions to ask before you book

**How will you know it worked?** Name the number and the target. If the
answer is "more sales", the goal is a purchase event and the target is a cost
per purchase or a return on ad spend. If the answer is "people saw it", the
goal is reach or completed views.

**Who counts it?** A metric goal is counted by the seller, so the seller can
guarantee it. An event goal is counted by your event source, so you need one
set up, and the seller can only aim for it unless it can read your events.
A vendor-measured goal is counted by the vendor.

**Is the seller liable?** Only when the commitment kind is `guaranteed`: a
fixed price on the outcome itself with guaranteed delivery or a makegood
policy. A best-effort target, however confident the prose, leaves the risk
with you. Read the commitment, not the pitch.


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