---
updatedAt: 2026-10-01T22:27:52.000Z
agentTools:
  projectIndex: https://developer.sovrn.com/llms.txt
---

# Deal lifecycle

How a deal's status changes and how to observe it.

A deal's status comes from its buyers: it is worked out from the state of each
buyer on the deal, and you observe it through the read endpoints. A deal with a
future start date is created as `scheduled` and becomes `active` on its start
date. You can also set the status yourself when the deal reads
`statusSettable: true`, which a read of the single deal reports (see
[Changing a deal's status](#changing-a-deals-status)).

## Deal types

`type` on a deal request selects how buyers reach the deal. It is chosen at
creation and cannot be changed afterwards.

| `type`          | What it is                                                                                                                                                                                                                                          |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pmp` (default) | A private marketplace deal. Every buyer carries **at least one** `seatIds` entry: the seats on that DSP that may transact. Omitting `type` is the same as sending `pmp`.                                                                            |
| `open`          | A non-seat deal: any buyer on the DSP can transact. Each buyer carries the `partner` **only**. A buyer that lists any seat in `seatIds` is rejected; an empty `seatIds` array is accepted. On DV360 an open deal appears as an **Auction Package**. |

```json
{
  "type": "open",
  "buyers": [{ "partner": "dv360" }]
}
```

Two consequences of `type` being fixed at creation:

* `PATCH /deal-requests/{id}` does not accept `type`. Sending it returns `400`.
* Buyers on an `open` deal cannot be edited. A `PATCH` that includes `buyers`
  on an open deal returns `400`; to change the buyer, create a new deal request.

> 📘 DSP-specific requirements
>
> Some DSPs require fields this API otherwise treats as optional. See
> [Demand partners](https://developer.sovrn.com/docs/demand-partners) for the requirements that apply to a
> given buyer before you submit.

## Statuses

| Status       | Meaning                                                                                                                                                                                                                                                    |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `active`     | Live and eligible to transact.                                                                                                                                                                                                                             |
| `scheduled`  | Its start date is in the future; becomes `active` on that date.                                                                                                                                                                                            |
| `paused`     | Temporarily not transacting. You can pause a deal yourself (see [Changing a deal's status](#changing-a-deals-status)), and Sovrn can too.                                                                                                                  |
| `review`     | A buyer reported an error, or the deal's buyers are not all in the same state. When a buyer did not accept the deal, the deal says which buyer and why in `buyerIssues` (see [When a buyer does not accept a deal](#when-a-buyer-does-not-accept-a-deal)). |
| `dsp review` | Awaiting DSP confirmation (applies to certain buyers).                                                                                                                                                                                                     |
| `archived`   | Terminated, for good: an archived deal cannot be changed. Excluded from list reads unless you ask for `?status=archived`.                                                                                                                                  |

> 📘 Judging freshness
>
> `GET /deal-requests/{id}` refreshes the status from source (cached \~30s) and
> reports `statusAsOf`. If that refresh fails, it returns the last-known status
> with a `200` (not an error), so always read `statusAsOf` to judge freshness.
> The list endpoint does **not** refresh; poll the by-id endpoint for current
> status.

### When a buyer does not accept a deal

Some DSPs check a deal after it is created and can turn it down. The deal then
reads `review`, and `GET /deal-requests/{id}` adds `buyerIssues`, one entry for
each issue that buyer's DSP reported:

```json
{
  "status": "review",
  "buyerIssues": [
    {
      "partner": "dv360",
      "message": "This value is below the minimum this buyer accepts.",
      "field": "pricing.floor"
    },
    {
      "partner": "dv360",
      "message": "This buyer does not accept this value.",
      "field": "buyers.0.seatIds"
    }
  ]
}
```

* `partner` is the buyer, as it appears in the deal's `buyers`. On a deal with
  several buyers, only a buyer that did not accept the deal is named, and the
  deal reads `review` all the same.
* `field`, when present, is the field to correct, as a path into the deal
  request: one of `schedule.endDate`, `description`, `pricing.floor`, or
  `buyers.N.seatIds` for the seats of the buyer at position N in `buyers`,
  counting from 0.
* `message` is written by this API, not by the DSP.

An issue that maps to no field has no `field`, and its message is always:

`This buyer did not accept the deal. Saving the deal again retries it.`

Correct the fields named with `PATCH /deal-requests/{id}`. Saving the deal sends
it to the buyer again, which is also how an issue without a `field` is retried:
a `PATCH` with an empty body, `{}`, saves the deal unchanged. The `PATCH` does
not wait for the buyer's answer, so read the deal again to see the outcome:
`buyerIssues` is gone once the buyer no longer reports an issue.

`buyerIssues` is absent from a deal whose buyers reported nothing, from list
items and from the `200` of a `PATCH`. It can also be absent when the buyers'
state could not be read; `status` still reads `review`.

## Changing a deal's status

`PATCH /deal-requests/{id}` accepts a `status`, so you can pause a deal and
start it again without involving Sovrn operations:

```json
{ "status": "paused" }
```

Four values may be sent. The rest of the statuses in the table above are
produced by the deal's buyers and cannot be set:

| `status`    | Send it to                                                                                                                                                                              |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `paused`    | Stop the deal transacting. Reversible.                                                                                                                                                  |
| `active`    | Resume a paused deal.                                                                                                                                                                   |
| `scheduled` | The same as `active`: it resumes a paused deal. The start date decides which of the two the deal reads back.                                                                            |
| `archived`  | End the deal for good. Every later `PATCH` that passes validation returns `502`, and the deal stays archived. Archived deals leave the default list; list them with `?status=archived`. |

Sending `review`, `dsp review`, or any value outside the four returns `400`
naming the four. `status` is a normal merge-patch field: send it alone, or
alongside any other edit in the same request (see
[Editing a deal](#editing-a-deal)).

> 🚧 Not every DSP
>
> `status` is rejected with `400` on a deal whose buyers are **all** on a DSP
> that manages deal status through its own integration (`dv360` today). Such a
> DSP manages its deals' status itself, and this API does not change it. On a
> deal that mixes such a buyer with others, the others are changed and the
> DSP's buyer is left as it is, so the status you send does not always stick:
> see [Ask the deal, not the DSP](#ask-the-deal-not-the-dsp) and
> [Demand partners](https://developer.sovrn.com/docs/demand-partners#deals-you-can-pause-yourself).

### Ask the deal, not the DSP

`GET /deal-requests/{id}` and the `200` from `PATCH /deal-requests/{id}` carry a
`statusSettable` boolean. Read it instead of keeping your own list of which DSPs
allow a status change: the list changes, and the deal already knows.

```json
{
  "statusSettable": false
}
```

`true` means every buyer on the deal is one whose status this API sets, so the
deal resolves to the status you send, subject to the start-date rule below.

`statusSettable` is worked out from the deal's buyers alone, so an archived deal
can still read `true`. An archived deal cannot be changed, whatever it reads.

`false` is deliberately **broader** than the `400` above. It covers two cases:

* **every** buyer is on a DSP that manages its own deal status: sending
  `status` returns `400`, as described in the callout above; and
* **some** buyers are: sending `status` is accepted and returns `200`, and the
  other buyers are changed. The DSP's buyer keeps its own state, and the deal's
  status is worked out from all of its buyers together. Only `paused` on a
  `pmp` deal always resolves as sent. Any other value resolves as sent only if
  the DSP's buyer is already in that state on its side, and otherwise the deal
  reads back `review`. A deal you tried to archive that way is not archived and
  still appears in list results.

So `statusSettable` answers "should I offer a status control for this deal?",
not "will this `PATCH` return `200`?". The two differ only on that second case,
and treating `false` as "do not offer it" is correct for both.

List items and the `201` from a create do not carry `statusSettable`, so read
the deal itself before offering the control.

Two things to expect from the response. `status` on the `200` is the status the
deal actually resolved to, which is not always the one you sent: `active` and
`scheduled` are derived from the start date, so a deal set `active` before its
start date reads back `scheduled`, one set `scheduled` after its start date
reads back `active`, and a deal whose buyers end up in different states reads
back `review`. And the status is written to each buyer in turn, after the other
fields in the request have been applied, so a failure partway can leave the
buyers in different states. Re-send the same request until it returns `200`
(see [Errors](https://developer.sovrn.com/docs/errors#retrying)).

## Editing a deal

`PATCH /deal-requests/{id}` follows merge-patch rules:

* Send only the fields you change. A field you leave out keeps its value.
* `buyers` and `targeting` replace the previous arrays whole; they are not
  merged into them.
* `description: null` clears the description.
* `schedule.endDate` and `pricing.floor` can be changed but not cleared:
  `null` returns `400`.
* `targeting` cannot be cleared: `null` or `[]` returns `400`. To remove a
  deal's targeting, switch it to Run of Network with `runOfNetwork: true` (see
  [Targeting](https://developer.sovrn.com/docs/targeting#run-of-network)).
* `type` cannot change: sending it returns `400` (see
  [Deal types](#deal-types)).
* `status` can be sent too (see
  [Changing a deal's status](#changing-a-deals-status)).
* Send the body as `application/json`. A `PATCH` sent as
  `application/merge-patch+json` returns `415`.

A deal with a `dv360` buyer has further rules on an edit; see
[Demand partners](https://developer.sovrn.com/docs/demand-partners#dv360-requirements).