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).
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. |
{
"type": "open",
"buyers": [{ "partner": "dv360" }]
}Two consequences of type being fixed at creation:
PATCH /deal-requests/{id}does not accepttype. Sending it returns400.- Buyers on an
opendeal cannot be edited. APATCHthat includesbuyers
on an open deal returns400; to change the buyer, create a new deal request.
DSP-specific requirementsSome DSPs require fields this API otherwise treats as optional. See
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), 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). |
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
reportsstatusAsOf. If that refresh fails, it returns the last-known status
with a200(not an error), so always readstatusAsOfto 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:
{
"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"
}
]
}partneris the buyer, as it appears in the deal'sbuyers. On a deal with
several buyers, only a buyer that did not accept the deal is named, and the
deal readsreviewall the same.field, when present, is the field to correct, as a path into the deal
request: one ofschedule.endDate,description,pricing.floor, or
buyers.N.seatIdsfor the seats of the buyer at position N inbuyers,
counting from 0.messageis 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:
{ "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).
Not every DSP
statusis rejected with400on a deal whose buyers are all on a DSP
that manages deal status through its own integration (dv360today). 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 and
Demand partners.
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.
{
"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
statusreturns400, as described in the callout above; and - some buyers are: sending
statusis accepted and returns200, 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. Onlypausedon a
pmpdeal 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 backreview. 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).
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.
buyersandtargetingreplace the previous arrays whole; they are not
merged into them.description: nullclears the description.schedule.endDateandpricing.floorcan be changed but not cleared:
nullreturns400.targetingcannot be cleared:nullor[]returns400. To remove a
deal's targeting, switch it to Run of Network withrunOfNetwork: true(see
Targeting).typecannot change: sending it returns400(see
Deal types).statuscan be sent too (see
Changing a deal's status).- Send the body as
application/json. APATCHsent as
application/merge-patch+jsonreturns415.
A deal with a dv360 buyer has further rules on an edit; see
Demand partners.
Updated about 14 hours ago

