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

# Autonomy and auto-select

> Choose per campaign whether you stage products yourself or let Semicola select them, and run auto-select on a draft campaign.

Autonomy settings say how independently Semi works on a campaign. The setting is saved on the
campaign, so you don't repeat it in every chat.

## Two dimensions, three modes

| Dimension            | Controls                                                                                |
| -------------------- | --------------------------------------------------------------------------------------- |
| `inventorySelection` | Whether you (or Semi, with your approval) stage products, or the platform selects them. |
| `rebriefing`         | Whether a change to the campaign brief waits for your approval.                         |

Each dimension takes one mode:

| Mode        | Meaning                                                                            |
| ----------- | ---------------------------------------------------------------------------------- |
| `manual`    | You act; Semi suggests. This is the effective mode when nothing is saved.          |
| `propose`   | Semi prepares the action and asks for an explicit yes before it runs.              |
| `automatic` | The platform acts, with the campaign's brief and budget as the standing authority. |

What each mode does in Semicola today:

* **`inventorySelection: "automatic"`**: the platform owns product selection. You pick products with
  [auto-select](#auto-select-products), and manual staging is refused: `save_media_buy` (products or a
  proposal) and `POST /api/v2/buyer/media-buys/batch` answer `409 CONFLICT` with
  `details.reason: "automatic_inventory_selection"` ("This campaign's inventory selection is automatic,
  so the platform picks its products and manual staging is refused. Set autonomy.inventorySelection to
  manual or propose to stage products yourself.").
* **`inventorySelection: "manual"` or `"propose"`**: you stage products yourself from proposals or
  discovery (see [Media buys and packages](/buy/media-buys-and-packages)); auto-select is refused.
* **`inventorySelection: "automatic"`** also lets Semi run `auto_select_products` without asking for
  a yes each time. Auto-select stays inside the campaign budget and contacts no seller.
* **`rebriefing: "automatic"`**: a `save_campaign` update that changes only the brief applies without
  asking for a yes. Any other change in the same call (budget, flight, name, phase) still asks. With
  `manual` or `propose`, every brief change asks.

A standing approval never applies to a [tainted](/setup/semi-confirmations) turn (one where Semi
has read outside content); Semi asks then.

Launching always needs a person's confirmation, in every mode. Autonomy never lets Semi go live on its
own.

## Set autonomy

Pass `autonomy` when you create or update a campaign (`save_campaign`, `POST /api/v2/buyer/campaigns`
or `PUT /api/v2/buyer/campaigns/{id}`). Each dimension is optional, but at least one must be present;
an omitted dimension keeps its current value.

```json theme={null}
{
  "campaignId": "cmp_…",
  "expectedRevision": 3,
  "autonomy": { "inventorySelection": "automatic" }
}
```

A change is recorded in the campaign's activity as an **Autonomy** change.

When you create a campaign without `autonomy`, it copies its advertiser's setting. Advertisers
created in Semicola start at `manual` for both dimensions (change that with `save_advertiser` or
`PUT /api/v2/buyer/advertisers/{id}`). When neither the campaign nor its advertiser has a saved value,
the effective mode is `manual`.

## Read it

Campaign reads return `autonomy` as saved (`{ "inventorySelection": …, "rebriefing": … }`), or `null`
when nothing is saved on the campaign. The campaign workspace shows the effective modes under
**Controls** as **Inventory selection** and **Re-briefing** (**Manual**, **Propose** or **Automatic**),
marked when the campaign differs from its advertiser. Autonomy is per campaign: changing one campaign
doesn't change the others.

## Auto-select products

Auto-select picks a product set for a draft campaign from its discovery session and splits the budget
across it. It contacts no seller: the result is staged draft buys you review and launch as usual.

| Surface | Call                                                     |
| ------- | -------------------------------------------------------- |
| MCP     | `auto_select_products` with `campaignId`                 |
| REST    | `POST /api/v2/buyer/campaigns/{id}/auto-select-products` |

The campaign must be `DRAFT`, have `autonomy.inventorySelection: "automatic"`, have a discovery
session (run `discover_products` or `request_proposals` for it first) and have a budget. Otherwise the
call answers `400 VALIDATION_ERROR` naming what's missing.

```json theme={null}
{
  "maxProducts": 8,
  "minBudgetPerProduct": 2500,
  "refine": [
    { "scope": "request", "ask": "more video, less display" },
    { "scope": "product", "id": "…", "action": "moreLikeThis" },
    { "scope": "product", "id": "…", "action": "omit" }
  ]
}
```

| Field                 | Notes                                                                                                                         |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `maxProducts`         | 1–50. Default 5.                                                                                                              |
| `minBudgetPerProduct` | Each selected product gets at least this much; fewer products are picked if the budget can't cover it.                        |
| `refine[]`            | Up to 50. `scope: "request"` with an `ask`; `scope: "product"` with an `id` and `action` `include`, `omit` or `moreLikeThis`. |

Each call **replaces** the previous selection: earlier draft buys on the campaign are archived and the
new products are staged, one draft buy per seller (and per [channel group](/buy/channel-groups) when the
campaign defines groups). Pass product ids exactly as discovery returned them.

The answer carries `discoveryId`, `selectedProducts[]` (`productId`, `name`, `salesAgentId`,
`groupId`, `groupName`, `cpm`, `budget`, `pricingOptionId`, `channelGroupId`), `budgetContext`
(`campaignBudget`, `totalAllocated`, `remainingBudget`, `currency`), `productCount`,
`previouslySelectedCount`, a `selectionRationale` and the `selectionMethod`:

| `selectionMethod` | How products were ranked                                                |
| ----------------- | ----------------------------------------------------------------------- |
| `scoring`         | The sellers' own proposal allocations for the products.                 |
| `measurability`   | No proposal allocations; products with a published forecast rank first. |
| `cpm_heuristic`   | Neither; lower CPM ranks first.                                         |

Refinement asks are read as channel preferences: "more video" favors online video and CTV products,
"less display" ranks display lower, and "no display" drops it. `include` keeps a product in the set,
`omit` drops it, and `moreLikeThis` favors products on the same channels.

## Related

* [Campaign](/buy/campaign)
* [Media buys and packages](/buy/media-buys-and-packages)
* [Product discovery](/buy/product-discovery)
