---
title: "Manage PMP deals on a campaign"
description: "Add, edit and remove private-marketplace deal rows on a campaign, switch it to a private auction, and understand how the rows reach DSP bid requests."
type: "howto"
audience: [network-manager]
keywords: [PMP, private marketplace, deal, deal ID, buyer seat, private auction, bid floor, first price, second price]
ui_path: "Account → Advertisers → advertiser → campaign → RTB PMP deals"
---

Fetch the complete documentation index at: https://epom.com/ad-server/docs/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Manage PMP deals on a campaign

The **RTB PMP deals** card on a campaign stores private-marketplace deal terms — deal ID, buyer
seat, floor price, auction type, country — and the platform copies them into every OpenRTB
bid request that campaign sends to its DSP partner. This page documents the card itself:
fields, validation, the private-auction toggle and the row lifecycle. For the end-to-end
recipe (negotiating terms, structuring campaigns per deal, verifying and reporting delivery)
see [Sell premium inventory through PMP private deals](https://epom.com/ad-server/docs/use-cases/pmp-private-deals.md).

## Who this is for

Network managers managing private-marketplace terms on a campaign. If you don't see the **RTB PMP deals**
card, ask your network admin for the *RTB PMP Deals* permission. Managing the card also needs a
campaign you own or hold as **Can edit**.

## Prerequisites

- A **saved campaign** — the card exists only on the edit page, not on the create form.
- [OpenRTB (DSP) banners](https://epom.com/ad-server/docs/guides/advertising/banner-openrtb-dsp.md) in the campaign: deal rows travel inside
  the bid requests those banners generate, so without them the deals never leave the platform.
- The deal terms from the buyer: deal ID string, buyer seat ID, floor price, auction type,
  covered countries.

## Steps

1. Open **Account → Advertisers → advertiser → campaign** and scroll to the **RTB PMP deals**
   card (that is its name on screen and in the Features rail). Turn the card's **switch on** — deal rows are only attached to bid requests while
   the switch is on.
   ![PMP deals card](https://epom.com/docs-images/ad-server/pmp-deals/pmp-deals-card.webp)
2. Optionally turn on **Private auction**. This is saved immediately (the toast reads "PMP type
   changed to private", or "…to public" when you turn it off) and marks the campaign's bid
   requests as private-auction — only bids referencing a valid deal are then accepted.
3. Click **Add** and fill the deal terms. The dialog carries the card's name (*RTB PMP deals*)
   rather than its own, **Country** starts at *Global*, **Auction type** at *First price* and
   **Bid floor** at 0:
   ![The deal dialog](https://epom.com/docs-images/ad-server/pmp-deals/pmp-deal-add-modal.webp)
4. Click **Add** in the modal footer. It stays greyed until **Deal ID** and **Buyer ID** are filled.
   The row appears in the grid and a "Done" toast confirms — rows save individually; there is no
   card-level Save button.
5. Edit a row later with the pencil icon (same modal, **Save**, also greyed while Deal ID or Buyer
   ID is empty). To remove rows, tick them and click **Delete (N)**, then confirm "Delete N
   record(s)?".

## Options and fields

| Field | What it does | Default | Validation |
|---|---|---|---|
| Deal ID | The external deal string both sides reference; the buyer's bids must carry it back | empty | Required |
| Buyer ID | The buyer's seat ID; sent as the deal's allowed seat (`wseat`) | empty | Required |
| Country | Country the row applies to, or **Global** (`*`) | Global | Required; must be an ISO alpha-2 code or `*` |
| Auction type | *First price*, *Second price* or *Bid floor price* (fixed-price deal — the win clears at exactly the floor) | First price | Required |
| Bid floor | The negotiated minimum price for this deal | 0 | 0 or greater. 99 999.999999 at most |

The fields are listed in the dialog's order. The grid shows the same five values in another order —
**Deal ID**, **Buyer ID**, **Auction type**, **Country**, **Bid floor** — sorts client-side and
refreshes with the reload button. Over the API a failed check answers with the message itself, for
example "Deal ID is empty.", "Bid floor should be positive." or "Please provide ISO alpha-2 country
code or * for global value."; the dialog's own button stays disabled instead. What each auction type means commercially — and how deal bids are treated in the
auction — is covered in the [PMP recipe](https://epom.com/ad-server/docs/use-cases/pmp-private-deals.md#how-the-auction-treats-deal-bids).

## How rows become deals in bid requests

For each bid request the campaign sends, the platform attaches the deal rows whose
**Country matches the request's country**, plus every **Global** row, into the OpenRTB
`pmp` object (deal ID, floor, auction type, buyer seat). The `pmp.private_auction` flag
follows the card's Private auction toggle. Rows are deduplicated, so two identical rows do
not produce two deals. Changes are picked up when the ad-serving cache next reloads — they
are not instantaneous.

## Corner cases and gotchas

> **Corner case:** the card only shows on an **existing** campaign. On the create form there
> is no RTB PMP deals card — save the campaign first.

> **Corner case:** a deal with the same **Deal ID + Buyer ID + Country** as an existing row
> is rejected ("PMP Deal with such deal ID, buyer ID and country already exists"). The same
> deal ID with a different country is fine — that's how you scope one deal to several
> countries.

> **Corner case:** switching the card **off does not delete the rows** — it only stops them
> from being attached to bid requests. Switch it back on and the same deals resume.

> **Corner case:** the **Private auction** toggle saves on click, independently of anything
> else on the page — there is no way to stage it together with other campaign changes.

> **Corner case:** a country code the platform cannot resolve renders in the grid as
> `XX (Can't parse)`. The row still exists; fix it via the pencil editor.

> **Corner case:** if the card is invisible to you but was previously enabled, the deals
> keep working — visibility is your permission, enforcement is the campaign's stored state.

> **Corner case:** over the REST API (tag **PMP Deals**) list deals with
> `GET /rest-api/campaign/{campaignId}/pmp-deals.do`, create with `POST …/{campaignId}/pmp-deal.do`,
> replace with `POST /rest-api/campaign/pmp-deal/{id}.do` — all five fields are required, it is not a
> partial update — and remove with `POST /rest-api/campaign/pmp-deals/delete.do` (`ids`). The
> campaign's on/off switch is `…/{campaignId}/pmp-deals/enable.do` and `…/disable.do` (`404` for an
> unknown or deleted campaign); deals created through the API stay dormant until the switch is on.
> See [Network & misc API](https://epom.com/ad-server/docs/api/network-and-misc.md).

## Per-role notes

- **Network manager, advertiser** — the card appears only once your network administrator grants *RTB PMP Deals*;
  managing it also needs a campaign you own or hold as **Can edit**.
- **Can view share** — the grid and the toggles are visible but disabled; there is no deal
  management on a campaign you cannot edit.

## Related

- [Sell premium inventory through PMP private deals](https://epom.com/ad-server/docs/use-cases/pmp-private-deals.md) — the end-to-end recipe
- [Epom PMP deal types compared](https://epom.com/ad-server/docs/guides/advertising/pmp-deal-types-compared.md) — first/second/bid-floor decision table
- [Create and edit a campaign](https://epom.com/ad-server/docs/guides/advertising/campaigns.md)
- [OpenRTB (DSP) banners](https://epom.com/ad-server/docs/guides/advertising/banner-openrtb-dsp.md)
- [Plug programmatic DSP demand](https://epom.com/ad-server/docs/use-cases/programmatic-dsp-demand.md)
- [Configure DSP partners](https://epom.com/ad-server/docs/guides/admin/dsp-partners.md)