Connect CTV supply and demand to Brand+

Verve Brand+ CTV integration guide

OpenRTB integration for Verve’s Brand+ (B+) marketplace, for CTV supply and demand partners.

[!NOTE]
Draft v0.1 for review. Supports OpenRTB 2.5 and 2.6, VAST InLine and Wrapper, and first-price auctions only (at = 1).

Start here

I am…Read in this order
📺 A publisher or SSP sending CTV inventorySetup → Ad request → Ad response → Ad pods
💰 A DSP buying CTVSetup → Bid request → Bid response → Ad pods
🔎 Looking something up2.5 vs 2.6 · Macros · Enums · Troubleshooting · Glossary

Legend used in every field table: 🔴 Required · 🔵 Recommended · ⚪ Optional. Click any ▶ row to expand it.

Contents

  1. How a CTV ad moves through Brand+
  2. Supply partners: Setup, Ad request, Ad response
  3. Demand partners: Setup, Bid request, Bid response
  4. Ad pods
  5. Where fields go in 2.5 vs 2.6
  6. Macros and tracking
  7. Enum reference
  8. Troubleshooting
  9. Glossary

1. How a CTV ad moves through Brand+

sequenceDiagram
    participant P as Publisher / SSP
    participant B as Brand+
    participant D as DSP
    P->>B: 1. Ad request (OpenRTB 2.5 or 2.6)
    B->>D: 2. Bid request (one per DSP, one per pod slot)
    D-->>B: 3. Bid response (VAST in adm)
    B-->>P: 4. Ad response (winning VAST + Brand+ tracking)
StepMessageDirectionDetails
1Ad requestPublisher to Brand+2.2
2Bid requestBrand+ to DSP3.2
3Bid responseDSP to Brand+3.3
4Ad responseBrand+ to publisher2.3

Back to top


2. Supply partners

2.1 Setup

Checklist

  • Send requests to the regional endpoint closest to your traffic (below).
  • Send the header x-openrtb-version with 2.5 or 2.6.
  • Put your Verve (Brand+) publisher ID in app.publisher.id.
  • Put the AdBreak ID in imp.tagid.
  • Set at to 1.

[!WARNING]
Without the x-openrtb-version header, requests are processed as OpenRTB 2.3, so 2.5 and 2.6 fields may be ignored.

Endpoints

RegionEndpoint
US Easthttps://ortb26-us-east-1.ad.smaato.net/oapi/exchange/ortb26
EU Westhttps://ortb26-eu-west-1.ad.smaato.net/oapi/exchange/ortb26
APAChttps://ortb26-ap-southeast-1.ad.smaato.net/oapi/exchange/ortb26

Some partners get a dedicated endpoint instead; your Verve account manager will share it. No token goes in the URL: requests are identified by app.publisher.id and imp.tagid.

Connection requirements

ConnectionRequirement
ProtocolHTTPS. All published endpoints use HTTPS.
Compressiongzip-encoded requests are accepted (Content-Encoding: gzip).
QPSAgreed individually with each partner.
TimeoutSet tmax to the time you allow Verve to respond, in milliseconds.

[!CAUTION]
Requests are rejected with HTTP 422 when regs.coppa = 1; when no usable public IP is available (device.ip, device.ipv6 and the connection’s IP are all missing, private or reserved); or when the user is under 14.

2.2 Ad request

Your player or SSP asks Brand+ for an ad: one HTTPS POST containing an OpenRTB bid request. Send a whole ad pod as one request (see Ad pods).

Sample: standard ad request
{
  "id": "a1b2c3d4-0000-4000-8000-000000000001",
  "imp": [
    {
      "id": "a1b2c3d4-0000-4000-8000-000000000002",
      "video": {
        "mimes": ["video/mp4"],
        "linearity": 1,
        "minduration": 1,
        "maxduration": 120,
        "protocols": [2, 3, 5, 6],
        "startdelay": -1,
        "pos": 7,
        "battr": [3, 8, 9, 10, 12, 14, 17],
        "minbitrate": 1,
        "maxbitrate": 100000,
        "playbackmethod": [1],
        "boxingallowed": 1,
        "placement": 1,
        "skip": 0,
        "plcmt": 1,
        "w": 1920,
        "h": 1080,
        "sequence": 1,
        "ext": {
          "context": "adpod"
        }
      },
      "tagid": "<BRAND_PLUS_ADBREAK_ID>",
      "bidfloor": 9.0,
      "bidfloorcur": "USD",
      "instl": 0,
      "secure": 1,
      "metric": [
        {
          "type": "video_completion_rate",
          "value": 0.95,
          "vendor": "EXCHANGE"
        }
      ],
      "ssai": 3,
      "ext": {},
      "exp": 3600
    }
  ],
  "app": {
    "id": "<APP_ID>",
    "name": "Example CTV App",
    "bundle": "<STORE_APP_ID>",
    "storeurl": "https://channelstore.example.com/apps/example-ctv-app",
    "cat": [],
    "pagecat": [],
    "domain": "example-ctv-app.com",
    "publisher": {
      "id": "<BRAND_PLUS_PUBLISHER_ID>",
      "name": "Example Publisher"
    },
    "content": {
      "id": "",
      "title": "",
      "season": "0",
      "genre": "news",
      "producer": {
        "id": "",
        "name": "",
        "cattax": 1
      },
      "cat": [],
      "contentrating": "",
      "keywords": "",
      "language": "",
      "livestream": 1,
      "ext": {
        "network": "Example Network",
        "channel": ""
      },
      "cattax": 1
    },
    "ext": {
      "inventorypartnerdomain": "example-publisher.com"
    },
    "cattax": 1
  },
  "device": {
    "dnt": 0,
    "ua": "Roku/DVP-16.0 (16.0.4.842-51)",
    "ip": "192.0.2.1",
    "geo": {
      "country": "USA",
      "region": "CA",
      "city": "<CITY>",
      "zip": "<ZIP>",
      "type": 2,
      "lat": 0.0,
      "lon": 0.0,
      "ipservice": 3,
      "accuracy": 10000,
      "metro": "<DMA>"
    },
    "dpidsha1": "<SHA1_OF_DEVICE_ID>",
    "dpidmd5": "<MD5_OF_DEVICE_ID>",
    "make": "Roku",
    "model": "Digital Video player",
    "os": "Roku OS",
    "osv": "16.0",
    "devicetype": 7,
    "language": "",
    "ifa": "00000000-0000-0000-0000-000000000000",
    "lmt": 0,
    "ext": {
      "is_app": 1,
      "ifa_type": "rida"
    }
  },
  "user": {
    "id": "<USER_ID>",
    "ext": {
      "eids": [
        {
          "source": "example-id.com",
          "uids": [
            {
              "id": "<EID_UID>",
              "atype": 3,
              "ext": {
                "rtiPartner": "idl"
              }
            }
          ]
        }
      ]
    }
  },
  "at": 1,
  "tmax": 250,
  "cur": ["USD"],
  "bcat": ["IAB23-1", "IAB25-1", "IAB25-2", "IAB25-3", "IAB25-4", "IAB25-5", "IAB25-6", "IAB25-7", "IAB26", "IAB26-1", "IAB26-2", "IAB26-3", "IAB26-4"],
  "badv": ["blocked-advertiser.example"],
  "source": {
    "fd": 0,
    "tid": "c1b2c3d4-0000-4000-8000-000000000003",
    "ext": {
      "schain": {
        "ver": "1.0",
        "complete": 1,
        "nodes": [
          {
            "asi": "example-ssp.com",
            "sid": "<SELLER_ID>",
            "hp": 1
          }
        ]
      }
    }
  },
  "regs": {
    "coppa": 0,
    "gdpr": 0,
    "ext": {
      "gdpr": 0,
      "us_privacy": "1YNN"
    }
  },
  "cattax": 1
}
Sample: dynamic ad pod (OpenRTB 2.6), up to 4 ads filling 120 seconds
{
  "id": "ckvvbteojs4lovcb9rfg",
  "imp": [
    {
      "id": "1",
      "video": {
        "mimes": ["video/mp4"],
        "minduration": 5,
        "maxduration": 30,
        "protocols": [2, 3, 5, 6, 7, 8],
        "w": 1920,
        "h": 1080,
        "startdelay": 0,
        "plcmt": 1,
        "linearity": 1,
        "skip": 0,
        "playbackmethod": [1],
        "delivery": [1, 2],
        "podid": "pod-1",
        "podseq": 1,
        "poddur": 120,
        "maxseq": 4,
        "poddedupe": [1, 2]
      },
      "tagid": "<BRAND_PLUS_ADBREAK_ID>",
      "bidfloor": 10.0,
      "bidfloorcur": "USD",
      "secure": 1,
      "exp": 3600,
      "ssai": 3,
      "rwdd": 0
    }
  ],
  "app": {
    "id": "123456",
    "name": "Example CTV App",
    "bundle": "com.example.ctvapp",
    "storeurl": "https://www.example.com/apps/ctvapp",
    "cat": ["IAB1"],
    "publisher": {
      "id": "<BRAND_PLUS_PUBLISHER_ID>",
      "name": "Example Publisher"
    },
    "content": {
      "id": "ep-0001",
      "title": "Example Episode",
      "series": "Example Series",
      "genre": "Comedy",
      "cat": ["IAB1"],
      "contentrating": "TV-PG",
      "livestream": 0,
      "len": 1800,
      "language": "en",
      "prodq": 1,
      "context": 1,
      "cattax": 1,
      "network": {
        "id": "net-1",
        "name": "Example Network",
        "domain": "examplenetwork.com"
      },
      "channel": {
        "id": "chan-1",
        "name": "Example Channel",
        "domain": "examplechannel.com"
      }
    }
  },
  "device": {
    "ua": "Mozilla/5.0 (SMART-TV; Linux; Tizen 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/6.0 TV Safari/537.36",
    "ip": "192.0.2.1",
    "geo": {
      "country": "USA",
      "region": "CA",
      "metro": "803",
      "type": 2
    },
    "devicetype": 3,
    "make": "Samsung",
    "model": "Tizen TV",
    "os": "Tizen",
    "osv": "6.0",
    "ifa": "00000000-0000-0000-0000-000000000000",
    "lmt": 0,
    "dnt": 0,
    "language": "en",
    "connectiontype": 2,
    "ext": {
      "ifa_type": "tifa"
    },
    "sua": {
      "source": 2,
      "platform": {
        "brand": "Tizen",
        "version": ["6", "0"]
      },
      "mobile": 0,
      "model": "Example TV Model"
    }
  },
  "user": {
    "id": "user-0001",
    "eids": [
      {
        "source": "example-id.com",
        "uids": [
          {
            "id": "EXAMPLE_UID",
            "atype": 3
          }
        ]
      }
    ]
  },
  "at": 1,
  "tmax": 500,
  "cur": ["USD"],
  "bcat": ["IAB25", "IAB26"],
  "source": {
    "fd": 1,
    "tid": "ckvvbteojs4lovcb9rg0",
    "schain": {
      "ver": "1.0",
      "complete": 1,
      "nodes": [
        {
          "asi": "example-ssp.com",
          "sid": "1234",
          "rid": "ckvvbteojs4lovcb9rfg",
          "hp": 1
        }
      ]
    }
  },
  "regs": {
    "coppa": 0,
    "gdpr": 0,
    "us_privacy": "1YNN",
    "gpp": "DBABTA~1YNN",
    "gpp_sid": [6]
  }
}

Field reference

Expand an object to see its fields.

Required at a glance: BidRequest.id, BidRequest.imp, BidRequest.app, BidRequest.device, BidRequest.at, Imp.id, Imp.video, Imp.tagid, Video.mimes, Video.minduration, Video.maxduration, Publisher.id

BidRequest (10 fields, 5 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredID of the bid request, assigned by the exchange, and unique for the exchange’s subsequent tracking of the responses.
impobject array🔴 RequiredArray of Imp objects representing the impressions offered.
appobject🔴 RequiredDetails via an App object about the publisher’s app.Rejected if neither app nor site is sent. CTV uses app.
deviceobject🔴 RequiredDetails via a Device object about the user’s device to which the impression will be delivered.
userobject🔵 RecommendedDetails via a User object about the human user of the device; the advertising audience.
atinteger🔴 RequiredAuction type, where 1 = First Price, 2 = Second Price Plus.Brand+ runs first-price auctions only: send 1.
tmaxinteger🔵 RecommendedMaximum time in milliseconds the exchange allows for bids to be received, including Internet latency.
curstring array⚪ OptionalArray of allowed currencies for bids on this bid request using ISO-4217 alpha codes.If sent, must include USD, otherwise the request is rejected.
bcatstring array⚪ OptionalBlocked advertiser categories using the specified category taxonomy.
badvstring array⚪ OptionalBlock list of advertisers by their domains.
Source (4 fields)
FieldTypeRequirementWhat it isBrand+ rule
fdinteger🔵 RecommendedEntity responsible for the final impression sale decision, where 0 = exchange, 1 = upstream source.
tidstring🔵 RecommendedTransaction ID that must be common across all participants in this bid request.
pchainstring🔵 RecommendedPayment ID chain string containing embedded syntax described in the TAG payment ID Protocol v1.0.
schainobject⚪ OptionalThe links in the supply chain, and an indicator of whether the supply chain is complete.Required if you are not direct to Brand+. On 2.5, send as source.ext.schain.
Imp (11 fields, 3 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredA unique identifier for this impression within the context of the bid request.
videoobject🔴 RequiredA Video object; required if this impression is offered as a video ad opportunity.
tagidstring🔴 RequiredIdentifier for specific ad placement or ad tag that was used to initiate the auction.Your Brand+ (SPX) AdBreakId. Prebid Server integrations use imp.ext.bidder.adSpace.
bidfloorfloat🔵 RecommendedMinimum bid for this impression expressed in CPM.
bidfloorcurstring🔵 RecommendedCurrency specified using ISO-4217 alpha codes.Use USD.
secureinteger🔵 RecommendedFlag to indicate if the impression requires secure HTTPS URL creative assets and markup, where 0 = non-secure, 1 = secure.
displaymanagerstring🔵 RecommendedName of ad mediation partner, SDK technology, or player responsible for rendering ad. Recommended for video and/or apps.
displaymanagerverstring🔵 RecommendedVersion of ad mediation partner, SDK technology, or player responsible for rendering ad. Recommended for video and/or apps.
expinteger⚪ OptionalAdvisory as to the number of seconds that may elapse between the auction and the actual impression.
pmpobject⚪ OptionalA Pmp object containing any private marketplace deals in effect for this impression.Deal IDs are returned in the ad response only when enabled for your account.
ssaiinteger🔵 RecommendedIndicates if server-side ad insertion is in use: 0 = unknown, 1 = all client-side, 2 = assets stitched server-side but tracking fired client-side, 3 = all server-side.OpenRTB 2.6.
Video (25 fields, 3 required)
FieldTypeRequirementWhat it isBrand+ rule
mimesstring array🔴 RequiredContent MIME types supported.
mindurationinteger🔴 Required in 2.5, optional in 2.6Minimum video ad duration in seconds. Mutually exclusive with rqddurs.In 2.6, send either min/maxduration or rqddurs.
maxdurationinteger🔴 Required in 2.5, optional in 2.6Maximum video ad duration in seconds. Mutually exclusive with rqddurs.In 2.6, send either min/maxduration or rqddurs.
rqddursinteger array⚪ OptionalPrecise acceptable durations for video creatives in seconds. Targets the Live TV use case.OpenRTB 2.6. Use instead of min/maxduration.
protocolsinteger array🔵 RecommendedArray of supported video protocols. Refer to List: Creative Subtypes - Audio/Video in AdCOM 1.0.
winteger🔵 RecommendedWidth of the video player in device-independent pixels (DIPS).
hinteger🔵 RecommendedHeight of the video player in device-independent pixels (DIPS).
startdelayinteger🔵 RecommendedIndicates the start delay in seconds for pre-roll, mid-roll, or post-roll ad placements.
plcmtinteger🔵 RecommendedVideo placement type for the impression. Refer to List: Plcmt Subtypes - Video in AdCOM 1.0.Use 1 (instream) for CTV.
placementinteger⚪ OptionalDeprecated as of OpenRTB 2.6-202303. Use plcmt instead.Send plcmt instead; keep placement only for older integrations.
linearityinteger🔵 RecommendedIndicates if the impression must be linear, nonlinear, etc. If none specified, assume all are allowed.
skipinteger🔵 RecommendedIndicates if the player will allow the video to be skipped, where 0 = no, 1 = yes.
playbackmethodinteger array⚪ OptionalPlayback methods that may be in use. If none are specified, any method may be used.
deliveryinteger array⚪ OptionalSupported delivery methods. If none specified, assume all are supported.
minbitrateinteger⚪ OptionalMinimum bit rate in Kbps.
maxbitrateinteger⚪ OptionalMaximum bit rate in Kbps.
battrinteger array⚪ OptionalBlocked creative attributes. Refer to List: Creative Attributes in AdCOM 1.0.
sequenceinteger⚪ OptionalDeprecated as of OpenRTB 2.6. Use slotinpod.Not used to identify ad pods. To send a pod, use imp.video.podid (2.6) or imp.video.ext.podid (2.5).
podidstring⚪ OptionalUnique identifier indicating that an impression opportunity belongs to a video ad pod.OpenRTB 2.6. Required for ad pods.
podseqinteger🔵 Recommended for podsThe sequence (position) of the video ad pod within a content stream.OpenRTB 2.6.
poddurinteger⚪ OptionalTotal amount of time in seconds that advertisers may fill for a dynamic video ad pod, or the dynamic portion of a hybrid pod.OpenRTB 2.6. Required for dynamic or hybrid pods.
maxseqinteger🔵 Recommended for podsMaximum number of ads that may be served into a dynamic video ad pod.OpenRTB 2.6.
poddedupeenum array⚪ OptionalIndicates pod deduplication settings that will be applied to bid responses.OpenRTB 2.6.
slotinpodinteger⚪ OptionalFor video ad pods, indicates that the seller can guarantee delivery against the indicated slot position in the pod.OpenRTB 2.6.
mincpmpersecfloat⚪ OptionalMinimum CPM per second. A price floor for the dynamic portion of a video ad pod, relative to bid duration.OpenRTB 2.6.
App (7 fields)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔵 RecommendedExchange-specific app ID.
namestring🔵 RecommendedApp name (may be aliased at the publisher’s request).
bundlestring🔵 RecommendedThe store ID of the app in an app store. See the OTT/CTV Store Assigned App Identification Guidelines.
storeurlstring🔵 RecommendedApp store URL for an installed app; for IQG 2.1 compliance.
catstring array⚪ OptionalArray of IAB Tech Lab content categories of the app. The taxonomy is defined by the cattax field.
domainstring⚪ OptionalDomain of the app.
ext.inventorypartnerdomain (Verve ext)—🔵 RecommendedDomain of the partner whose app-ads.txt authorises the sale.Forwarded to DSPs.
Publisher (1 field, 1 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredExchange-specific seller ID. Corresponds to a seller_id in the exchange’s sellers.json file.Your Brand+ (SPX) publisher ID. Prebid Server integrations use imp.ext.bidder.publisherId.
Content (17 fields)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔵 RecommendedPublisher-provided ID uniquely identifying the content.
titlestring🔵 RecommendedContent title.
seriesstring⚪ OptionalContent series.
seasonstring⚪ OptionalContent season.
episodeinteger⚪ OptionalEpisode number.
genrestring🔵 RecommendedGenre that best describes the content.
catstring array🔵 RecommendedArray of IAB Tech Lab content categories that describe the content.
cattaxinteger🔵 RecommendedThe taxonomy in use. Refer to List: Category Taxonomies in AdCOM 1.0.
contentratingstring🔵 RecommendedContent rating.
livestreaminteger🔵 RecommendedMethod of broadcast of the content: 0 = not scheduled (e.g. VOD or user-initiated), 1 = scheduled (linear viewing).
languagestring🔵 RecommendedContent language using ISO-639-1-alpha-2. Only one of language or langb should be present.
leninteger🔵 RecommendedLength of content in seconds; appropriate for video or audio.
prodqinteger⚪ OptionalProduction quality. Refer to List: Production Qualities in AdCOM 1.0.
contextinteger⚪ OptionalType of content (game, video, text, etc.). Refer to List: Content Contexts in AdCOM 1.0.
producerobject⚪ OptionalDetails about the content Producer.
ext.network (Verve ext)—🔵 RecommendedVerve extension.OpenRTB 2.5: network name.
ext.channel (Verve ext)—🔵 RecommendedVerve extension.OpenRTB 2.5: channel name.
Network (1 field)
FieldTypeRequirementWhat it isBrand+ rule
namestring🔵 RecommendedNetwork the content is on.OpenRTB 2.6, as content.network.name.
Channel (1 field)
FieldTypeRequirementWhat it isBrand+ rule
namestring🔵 RecommendedChannel the content is on.OpenRTB 2.6, as content.channel.name.
Device (16 fields)
FieldTypeRequirementWhat it isBrand+ rule
uastring🔵 RecommendedBrowser user agent string. This field represents a raw user agent string from the browser.
suaobject🔵 RecommendedStructured user agent information defined by a UserAgent object.OpenRTB 2.6.
ipstring🔵 RecommendedIPv4 address closest to device.
ipv6string⚪ OptionalIP address closest to device as IPv6.
geoobject🔵 RecommendedLocation of the device assumed to be the user’s current location, defined by a Geo object.
devicetypeinteger🔵 RecommendedThe general type of device. Refer to List: Device Types in AdCOM 1.0.3 = connected TV, 7 = set-top box.
makestring🔵 RecommendedDevice make.
modelstring🔵 RecommendedDevice model.
osstring🔵 RecommendedDevice operating system.
osvstring🔵 RecommendedDevice operating system version.
ifastring🔵 RecommendedID sanctioned for advertiser use in the clear (not hashed).
ext.ifa_type (Verve ext)—🔵 RecommendedVerve extension.IFA type, for example tifa or rida.
lmtinteger🔵 Recommended“Limit Ad Tracking” signal commercially endorsed, where 0 = tracking is unrestricted, 1 = tracking must be limited.
dntinteger🔵 RecommendedStandard “Do Not Track” flag, where 0 = tracking is unrestricted, 1 = do not track.
languagestring⚪ OptionalBrowser language using ISO-639-1-alpha-2.
connectiontypeinteger⚪ OptionalNetwork connection type. Refer to List: Connection Types in AdCOM 1.0.
User (4 fields)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔵 RecommendedExchange-specific ID for the user.Send id or buyeruid.
buyeruidstring🔵 RecommendedBuyer-specific ID for the user as mapped by the exchange for the buyer.Send id or buyeruid.
eidsobject array🔵 RecommendedDetails for support of a standard protocol for multiple third party identity providers.On 2.5, send as user.ext.eids.
consentstring⚪ OptionalWhen GDPR regulations are in effect, contains the Transparency and Consent Framework’s Consent String.Required where GDPR applies. On 2.5, send as user.ext.consent.
Regs (5 fields)
FieldTypeRequirementWhat it isBrand+ rule
coppainteger⚪ OptionalFlag indicating if this request is subject to the COPPA regulations established by the USA FTC, where 0 = no, 1 = yes.Brand+ does not accept child-directed traffic: requests with coppa = 1 are rejected.
gdprinteger⚪ OptionalWhether the request is subject to GDPR regulations: 0 = No, 1 = Yes, omission indicates unknown.Required where GDPR applies. On 2.5, send as regs.ext.gdpr.
us_privacystring⚪ OptionalCommunicates signals regarding consumer privacy under US privacy regulation.Required where US privacy laws apply. On 2.5, send as regs.ext.us_privacy.
gppstring⚪ OptionalContains the Global Privacy Platform’s consent string.Required where GPP applies.
gpp_sidinteger array⚪ OptionalArray of the section(s) of the GPP string which should be applied for this transaction.Required where GPP applies.

Back to top

2.3 Ad response

Verve returns the winning ad using your request and impression IDs. The ad is a VAST file containing the advertiser’s video, plus Verve’s tracking URLs for impressions, errors, video progress and clicks.

Sample: ad response
{
  "id": "a1b2c3d4-0000-4000-8000-000000000001",
  "seatbid": [
    {
      "bid": [
        {
          "id": "d1b2c3d4-0000-0000-0000-000000000004",
          "impid": "a1b2c3d4-0000-4000-8000-000000000002",
          "price": 11.0,
          "adid": "<CREATIVE_ID>",
          "nurl": "https://tracking.brandplus.example/winnotice?ap=${AUCTION_PRICE}",
          "lurl": "https://tracking.brandplus.example/lossnotice?ap=${AUCTION_PRICE}&al=${AUCTION_LOSS}",
          "adm": "<VAST version=\"3.0\"><Ad id=\"dsp-bid-0001\"><InLine><AdTitle>Example Ad</AdTitle><Error><![CDATA[https://tracking.brandplus.example/error?code=[ERRORCODE]]]></Error><AdSystem version=\"1.0\">Verve</AdSystem><Impression><![CDATA[https://tracking.brandplus.example/impression]]></Impression><Impression><![CDATA[https://dsp.example/imp]]></Impression><Creatives><Creative><Linear><Duration>00:00:30.000</Duration><TrackingEvents><Tracking event=\"start\"><![CDATA[https://tracking.brandplus.example/start]]></Tracking><Tracking event=\"firstQuartile\"><![CDATA[https://tracking.brandplus.example/q1]]></Tracking><Tracking event=\"midpoint\"><![CDATA[https://tracking.brandplus.example/mid]]></Tracking><Tracking event=\"thirdQuartile\"><![CDATA[https://tracking.brandplus.example/q3]]></Tracking><Tracking event=\"complete\"><![CDATA[https://tracking.brandplus.example/complete]]></Tracking></TrackingEvents><MediaFiles><MediaFile delivery=\"progressive\" type=\"video/mp4\" bitrate=\"3500\" width=\"1920\" height=\"1080\"><![CDATA[https://cdn.dsp.example/ad_1920x1080.mp4]]></MediaFile></MediaFiles></Linear></Creative></Creatives></InLine></Ad></VAST>",
          "adomain": ["advertiser.example"],
          "bundle": "<ADVERTISER_APP_BUNDLE>",
          "iurl": "https://cdn.dsp.example/companion_1280x720.jpeg",
          "cid": "<CAMPAIGN_ID>",
          "burl": "https://tracking.brandplus.example/impression?ap=${AUCTION_PRICE}",
          "crid": "<CREATIVE_ID>",
          "cat": ["IAB9-30"],
          "w": 1280,
          "h": 720,
          "dur": 30,
          "ext": {
            "duration": 30
          }
        }
      ]
    }
  ],
  "bidid": "e1b2c3d4-0000-4000-8000-000000000005",
  "cur": "USD"
}

Field reference

Expand an object to see its fields.

Required at a glance: BidResponse.id, BidResponse.bidid, BidResponse.cur, Bid.id, Bid.impid, Bid.price, Bid.adm, Bid.nurl, Bid.adid, Bid.crid

BidResponse (3 fields, 3 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredID of the bid request to which this is a response.Echoes your request ID.
bididstring🔴 RequiredBidder generated response ID to assist with logging/tracking.
curstring🔴 RequiredBid currency using ISO-4217 alpha codes.USD.
Bid (22 fields, 7 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredBidder generated bid ID to assist with logging/tracking.Unique per winning ad, including each ad in a pod.
impidstring🔴 RequiredID of the Imp object in the related bid request.
pricefloat🔴 RequiredBid price expressed as CPM although the actual transaction is for a unit impression only.USD CPM.
admstring🔴 RequiredOptional means of conveying ad markup in case the bid wins; supersedes the win notice if markup is included in both.VAST. Brand+ returns the winning DSP’s VAST with its own impression, error and tracking events added.
nurlstring🔴 RequiredWin notice URL called by the exchange if the bid wins (not necessarily indicative of a delivered, viewed, or billable ad).
burlstring⚪ OptionalBilling notice URL called by the exchange when a winning bid becomes billable based on exchange-specific business policy.When configured for your account.
lurlstring⚪ OptionalLoss notice URL called by the exchange when a bid is known to have been lost.When configured for your account.
adidstring🔴 RequiredID of a preloaded ad to be served if the bid wins.Falls back to crid.
cridstring🔴 RequiredCreative ID to assist with ad quality checking.
cidstring⚪ OptionalCampaign ID to assist with ad quality checking.From the winning DSP bid.
adomainstring array⚪ OptionalAdvertiser domain for block list checking.From the winning DSP bid.
catstring array⚪ OptionalIAB Tech Lab content categories of the creative. The taxonomy is defined by the cattax field.From the winning DSP bid.
iurlstring⚪ OptionalURL without cache-busting to an image that is representative of the content of the campaign, for ad quality/safety checking.
bundlestring⚪ OptionalThe store ID of the app in an app store.
attrinteger array⚪ OptionalSet of attributes describing the creative. Refer to List: Creative Attributes in AdCOM 1.0.
w / hinteger⚪ OptionalWidth and height of the creative in device-independent pixels (DIPS).
durinteger⚪ OptionalDuration of the video or audio creative in seconds.Also sent as ext.duration. Left out when neither the bid nor its VAST gives a duration.
ext.duration (Verve ext)—⚪ OptionalVerve extension.Creative duration, mirroring dur.
podid (Verve ext)—⚪ OptionalThe IAB defines podid on the Video object of the request, not on the Bid.Pod the ad fills; sent for pod requests. 2.6 publishers get podid and ext.podid; 2.5 publishers get ext.podid only.
dealidstring⚪ OptionalReference to the deal.id from the bid request if this bid pertains to a private marketplace direct deal.Only when deal ID pass-back is enabled for your account.
apisinteger array⚪ OptionalList of supported APIs for the markup. If an API is not explicitly listed, it is assumed to be unsupported.Also sent as ext.apis.
ext.imptrackers (Verve ext)—⚪ OptionalVerve extension.When configured.

Back to top


3. Demand partners

3.1 Setup

Checklist. Send these to your Verve account manager; Verve configures the integration on its side.

  • Your CTV endpoint URLs (test and production) for each region you want traffic from.
  • Your requested QPS.
  • Whether your endpoints use HTTPS or HTTP.
  • Whether you want gzip-compressed bid requests.

[!IMPORTANT]
Verve sends traffic from the US, EU and APAC, and each region sends only to its own registered endpoint. If no endpoint is registered for a region, that region sends you no traffic.

ConnectionDetails
ProtocolHTTPS is recommended. HTTP endpoints can also be configured.
Compressiongzip compression of bid requests is available on request.
QPSConfigured individually for each DSP and agreed with Verve.
TimeoutRespond within the tmax value in each bid request.

3.2 Bid request

Brand+ turns the publisher’s ad request into a bid request for each DSP. On the way it:

  • appends its own node to the supply chain, sent as a JSON-encoded string in source.ext.schain and top-level ext.schain;
  • adds imp.ext.gpid, taken from imp.tagid when the ad request has none;
  • splits a pod into one OpenRTB 2.5 request per slot, with pod details in imp.video.ext;
  • standardises device and content values.
Sample: bid request
{
  "app": {
    "bundle": "<STORE_APP_ID>",
    "cat": ["IAB24"],
    "content": {
      "cattax": 1,
      "id": "<CONTENT_ID>",
      "contentrating": "TV-PG",
      "language": "en",
      "channel": {
        "name": "Example Channel"
      },
      "ext": {
        "channel": "Example Channel",
        "network": "Example Network"
      },
      "genre": "News",
      "network": {
        "name": "Example Network"
      },
      "producer": {},
      "season": "0",
      "livestream": 1
    },
    "domain": "example-ctv-app.com",
    "ext": {
      "inventorypartnerdomain": "example-publisher.com"
    },
    "id": "<APP_ID>",
    "keywords": "App",
    "name": "Example CTV App",
    "publisher": {
      "id": "<BRAND_PLUS_PUBLISHER_ID>",
      "name": "Example Publisher"
    },
    "storeurl": "https://channelstore.example.com/apps/example-ctv-app"
  },
  "at": 1,
  "bcat": ["IAB23-1", "IAB25-1", "IAB25-2", "IAB25-3", "IAB25-4", "IAB25-5", "IAB25-6", "IAB25-7", "IAB26", "IAB26-1", "IAB26-2", "IAB26-3", "IAB26-4"],
  "cur": ["USD"],
  "device": {
    "carrier": "<ISP>",
    "connectiontype": 2,
    "devicetype": 3,
    "dnt": 0,
    "dpidmd5": "<MD5_OF_DEVICE_ID>",
    "dpidsha1": "<SHA1_OF_DEVICE_ID>",
    "ext": {
      "ifa_type": "rida"
    },
    "geo": {
      "accuracy": 10000,
      "city": "<CITY>",
      "country": "USA",
      "ext": {
        "isp": "<ISP>",
        "org": "<ISP>"
      },
      "lat": 0.0,
      "lon": 0.0,
      "region": "CA",
      "type": 2,
      "zip": "<ZIP>",
      "metro": "<DMA>",
      "ipservice": 3
    },
    "h": 720,
    "ifa": "00000000-0000-0000-0000-000000000000",
    "ip": "192.0.2.1",
    "js": 1,
    "language": "en",
    "lmt": 0,
    "make": "Roku",
    "model": "DVP",
    "os": "Roku OS",
    "osv": "16.0",
    "pxratio": 0,
    "ua": "Roku/DVP-16.0 (16.0.4.842-51)",
    "w": 1280
  },
  "ext": {
    "pchain": "<PAYMENT_ID_CHAIN>",
    "schain": "{\n \"ver\": \"1.0\",\n \"complete\": 1,\n \"nodes\": [\n  {\n   \"asi\": \"example-ssp.com\",\n   \"sid\": \"<SELLER_ID>\",\n   \"hp\": 1\n  },\n  {\n   \"asi\": \"lkqd.net\",\n   \"sid\": \"<BRAND_PLUS_PUBLISHER_ID>\",\n   \"rid\": \"b1b2c3d4000000000000000000000001\",\n   \"hp\": 1\n  }\n ]\n}"
  },
  "id": "b1b2c3d4000000000000000000000001",
  "imp": [
    {
      "bidfloor": "9.0",
      "bidfloorcur": "USD",
      "exp": 6300,
      "ext": {
        "gpid": "<BRAND_PLUS_ADBREAK_ID>",
        "hb": 1,
        "is_rewarded_inventory": false,
        "metric": [
          {
            "type": "click_through_rate",
            "value": 0.01687,
            "vendor": "EXCHANGE"
          }
        ]
      },
      "id": "b1b2c3d4-0000-0000-0000-000000000002",
      "instl": 0,
      "metric": [
        {
          "type": "click_through_rate",
          "value": 0.01687,
          "vendor": "EXCHANGE"
        }
      ],
      "rwdd": 0,
      "secure": 1,
      "ssai": 3,
      "tagid": "<BRAND_PLUS_ADBREAK_ID>",
      "video": {
        "battr": [3, 8, 9, 10, 12, 14, 17],
        "boxingallowed": 1,
        "ext": {
          "orientation": "0"
        },
        "linearity": 1,
        "maxbitrate": 100000,
        "maxduration": 120,
        "mimes": ["video/mp4", "video/3gpp", "video/H264"],
        "minbitrate": 1,
        "minduration": 1,
        "placement": 1,
        "playbackend": 1,
        "playbackmethod": [1],
        "plcmt": 1,
        "pos": 7,
        "protocols": [2, 3, 5, 6],
        "skip": 0,
        "startdelay": -1,
        "w": 1920,
        "h": 1080,
        "sequence": 1
      },
      "pmp": {
        "deals": [
          {
            "id": "<DEAL_ID>",
            "bidfloor": "9.0",
            "at": 1
          }
        ]
      }
    }
  ],
  "regs": {
    "coppa": 0,
    "ext": {
      "agerange": "0",
      "consent": "",
      "gdpr": "0",
      "us_privacy": "1YNN"
    }
  },
  "source": {
    "ext": {
      "schain": "{\n \"ver\": \"1.0\",\n \"complete\": 1,\n \"nodes\": [\n  {\n   \"asi\": \"example-ssp.com\",\n   \"sid\": \"<SELLER_ID>\",\n   \"hp\": 1\n  },\n  {\n   \"asi\": \"lkqd.net\",\n   \"sid\": \"<BRAND_PLUS_PUBLISHER_ID>\",\n   \"rid\": \"b1b2c3d4000000000000000000000001\",\n   \"hp\": 1\n  }\n ]\n}"
    },
    "fd": 1,
    "pchain": "<PAYMENT_ID_CHAIN>",
    "tid": "c1b2c3d4-0000-4000-8000-000000000003"
  },
  "test": 0,
  "tmax": 235,
  "user": {
    "ext": {
      "eids": [
        {
          "source": "example-id.com",
          "uids": [
            {
              "id": "<EID_UID>",
              "atype": 3
            }
          ]
        }
      ]
    },
    "id": "<USER_ID>",
    "eids": [
      {
        "source": "example-id.com",
        "uids": [
          {
            "id": "<EID_UID>",
            "atype": 3
          }
        ]
      }
    ]
  }
}

Field reference

Expand an object to see its fields.

Required at a glance: BidRequest.id, BidRequest.at, BidRequest.tmax, BidRequest.cur, BidRequest.test, Imp.id, Imp.tagid, Imp.bidfloor, Imp.bidfloorcur, Imp.secure, Imp.exp, Imp.instl, Imp.rwdd, Imp.metric, Imp.ext.gpid, Video.mimes, Video.minduration, Video.maxduration, Video.protocols, Video.startdelay, Video.linearity, Video.skip, Video.plcmt, Video.pos, Video.playbackend, App.id, App.name, App.bundle, App.storeurl, App.cat, App.ext.inventorypartnerdomain, Publisher.id, Publisher.name, Device.ua, Device.ifa, Device.devicetype, Device.make / model / os / osv, Device.lmt, Device.dnt, Device.language, Device.geo, User.id, Source.fd, Source.tid, Source.pchain, Source.ext.schain, Regs.coppa, Regs.ext.gdpr / ext.consent / ext.us_privacy

BidRequest (8 fields, 5 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredID of the bid request, assigned by the exchange, and unique for the exchange’s subsequent tracking of the responses.
atinteger🔴 RequiredAuction type, where 1 = First Price, 2 = Second Price Plus.Auction type configured for the DSP (1 = first price).
tmaxinteger🔴 RequiredMaximum time in milliseconds the exchange allows for bids to be received, including Internet latency.
curstring array🔴 RequiredArray of allowed currencies for bids on this bid request using ISO-4217 alpha codes.Required USD.
testinteger🔴 RequiredIndicator of test mode in which auctions are not billable, where 0 = live mode, 1 = test mode.
bcatstring array⚪ OptionalBlocked advertiser categories using the specified category taxonomy.Publisher and Brand+ blocks.
badvstring array⚪ OptionalBlock list of advertisers by their domains.
wseatstring array⚪ OptionalAllowed list of buyer seats allowed to bid on this impression.
Imp (12 fields, 10 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredA unique identifier for this impression within the context of the bid request.
tagidstring🔴 RequiredIdentifier for specific ad placement or ad tag that was used to initiate the auction.
bidfloorfloat🔴 RequiredMinimum bid for this impression expressed in CPM.USD CPM.
bidfloorcurstring🔴 RequiredCurrency specified using ISO-4217 alpha codes.
secureinteger🔴 RequiredFlag to indicate if the impression requires secure HTTPS URL creative assets and markup, where 0 = non-secure, 1 = secure.
expinteger🔴 RequiredAdvisory as to the number of seconds that may elapse between the auction and the actual impression.
instlinteger🔴 Required1 = the ad is interstitial or full screen, 0 = not interstitial.
rwddinteger🔴 RequiredIndicates whether the user receives a reward for viewing the ad, where 0 = no, 1 = yes.
metricobject array🔴 RequiredAn array of Metric objects.Exchange-provided metrics, for example estimated CTR.
pmpobject⚪ OptionalA Pmp object containing any private marketplace deals in effect for this impression.Deals the DSP is eligible for.
ext.gpid (Verve ext)—🔴 RequiredVerve extension.Global placement ID. Sent by default; taken from imp.tagid when the ad request has none.
ext.tid / ext.tidt (Verve ext)—⚪ OptionalVerve extension.Impression-level transaction ID and its type. Sent to DSPs set up for transaction ID enrichment, on long-form video traffic.
Deal (4 fields)
FieldTypeRequirementWhat it isBrand+ rule
idstring⚪ OptionalA unique identifier for the direct deal.
bidfloorfloat⚪ OptionalMinimum bid for this impression expressed in CPM.
atinteger⚪ OptionalOptional override of the overall auction type of the bid request, where 1 = First Price, 2 = Second Price Plus.
wseatstring array⚪ OptionalAllowed list of buyer seats allowed to bid on this deal.
Video (25 fields, 10 required)
FieldTypeRequirementWhat it isBrand+ rule
mimesstring array🔴 RequiredContent MIME types supported.
mindurationinteger🔴 RequiredMinimum video ad duration in seconds. Mutually exclusive with rqddurs.
maxdurationinteger🔴 RequiredMaximum video ad duration in seconds. Mutually exclusive with rqddurs.
protocolsinteger array🔴 RequiredArray of supported video protocols. Refer to List: Creative Subtypes - Audio/Video in AdCOM 1.0.
startdelayinteger🔴 RequiredIndicates the start delay in seconds for pre-roll, mid-roll, or post-roll ad placements.
linearityinteger🔴 RequiredIndicates if the impression must be linear, nonlinear, etc. If none specified, assume all are allowed.
skipinteger🔴 RequiredIndicates if the player will allow the video to be skipped, where 0 = no, 1 = yes.
plcmtinteger🔴 RequiredVideo placement type for the impression. Refer to List: Plcmt Subtypes - Video in AdCOM 1.0.
posinteger🔴 RequiredAd position on screen. Refer to List: Placement Positions in AdCOM 1.0.7 (full screen) for CTV.
playbackendinteger🔴 RequiredThe event that causes playback to end. Refer to List: Playback Cessation Modes in AdCOM 1.0.
winteger⚪ OptionalWidth of the video player in device-independent pixels (DIPS).
hinteger⚪ OptionalHeight of the video player in device-independent pixels (DIPS).
placementinteger⚪ OptionalDeprecated as of OpenRTB 2.6-202303. Use plcmt instead.
playbackmethodinteger array⚪ OptionalPlayback methods that may be in use. If none are specified, any method may be used.
deliveryinteger array⚪ OptionalSupported delivery methods. If none is specified, assume all are supported.
minbitrateinteger⚪ OptionalMinimum bit rate in Kbps.
maxbitrateinteger⚪ OptionalMaximum bit rate in Kbps.
battrinteger array⚪ OptionalBlocked creative attributes. Refer to List: Creative Attributes in AdCOM 1.0.
boxingallowedinteger⚪ OptionalIndicates if letter-boxing of 4:3 content into a 16:9 window is allowed, where 0 = no, 1 = yes.
sequenceinteger⚪ OptionalDeprecated as of OpenRTB 2.6. Use slotinpod.Sent for ad pods.
ext.podid / ext.podseq / ext.sequence (Verve ext)—⚪ OptionalVerve extension.podid and sequence are sent on every pod slot; podseq only when the publisher sends it.
ext.slotinpod (Verve ext)—⚪ OptionalThe position in the pod that this slot’s bid is eligible for, from the publisher’s imp.video.slotinpod.Sent only when the publisher’s ad request states a slot.
ext.rqddurs (Verve ext)—⚪ OptionalThe exact creative durations the publisher accepts, from the publisher’s imp.video.rqddurs.Sent only when the publisher sends rqddurs. minduration and maxduration are then narrowed to its lowest and highest values.
ext.mincpmpersec (Verve ext)—⚪ OptionalMinimum CPM per second of ad duration, from the publisher’s imp.video.mincpmpersec.Sent only when the publisher sends it. Adjusted by Brand+ in the same way as imp.bidfloor.
ext.durfloors (Verve ext)—⚪ OptionalFloors by creative duration, from the publisher’s imp.video.durfloors: a list of duration bands, each with its own floor.Sent only when the publisher sends them. Adjusted by Brand+ in the same way as imp.bidfloor.
App (7 fields, 6 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredExchange-specific app ID.
namestring🔴 RequiredApp name (may be aliased at the publisher’s request).
bundlestring🔴 RequiredThe store ID of the app in an app store. See the OTT/CTV Store Assigned App Identification Guidelines.
storeurlstring🔴 RequiredApp store URL for an installed app; for IQG 2.1 compliance.
catstring array🔴 RequiredArray of IAB Tech Lab content categories of the app. The taxonomy is defined by the cattax field.
domainstring⚪ OptionalDomain of the app.
ext.inventorypartnerdomain (Verve ext)—🔴 RequiredVerve extension.Sent by default.
Publisher (3 fields, 2 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredExchange-specific seller ID. Corresponds to a seller_id in the exchange’s sellers.json file.Brand+ publisher ID.
namestring🔴 RequiredSeller name (may be aliased at the seller’s request).
domainstring⚪ OptionalHighest level domain of the seller.
Content (9 fields)
FieldTypeRequirementWhat it isBrand+ rule
id / title / series / seasonstring⚪ OptionalContent ID, title, series and season.Passed through from the publisher.
genrestring⚪ OptionalGenre that best describes the content.
cat / cattaxstring array / integer⚪ OptionalArray of IAB Tech Lab content categories that describe the content, and the taxonomy in use.
contentratingstring⚪ OptionalContent rating.
languagestring⚪ OptionalContent language using ISO-639-1-alpha-2.
leninteger⚪ OptionalLength of content in seconds; appropriate for video or audio.
livestreaminteger⚪ OptionalMethod of broadcast of the content: 0 = not scheduled (e.g. VOD or user-initiated), 1 = scheduled (linear viewing).
prodq / context / producerinteger / object⚪ OptionalProduction quality, type of content, and content producer.
ext.network / ext.channel (Verve ext)—⚪ OptionalVerve extension.Kept for DSPs that read the 2.5 extensions.
Network (1 field)
FieldTypeRequirementWhat it isBrand+ rule
namestring⚪ OptionalNetwork the content is on.Filled from the publisher’s 2.5 ext.network when needed.
Channel (1 field)
FieldTypeRequirementWhat it isBrand+ rule
namestring⚪ OptionalChannel the content is on.Filled from the publisher’s 2.5 ext.channel when needed.
Device (14 fields, 8 required)
FieldTypeRequirementWhat it isBrand+ rule
uastring🔴 RequiredBrowser user agent string. This field represents a raw user agent string from the browser.Privacy signals may remove or truncate device data.
ifastring🔴 RequiredID sanctioned for advertiser use in the clear (not hashed).
ext.ifa_type (Verve ext)—⚪ OptionalVerve extension.Passed through when the publisher sends it.
devicetypeinteger🔴 RequiredThe general type of device. Refer to List: Device Types in AdCOM 1.0.
make / model / os / osvstring🔴 RequiredDevice make, model, operating system and operating system version.
lmtinteger🔴 Required“Limit Ad Tracking” signal commercially endorsed, where 0 = tracking is unrestricted, 1 = tracking must be limited.
dntinteger🔴 RequiredStandard “Do Not Track” flag, where 0 = tracking is unrestricted, 1 = do not track.
languagestring🔴 RequiredBrowser language using ISO-639-1-alpha-2.
connectiontypeinteger⚪ OptionalNetwork connection type. Refer to List: Connection Types in AdCOM 1.0.Sent when present in the ad request or available from an IP lookup.
ipstring⚪ OptionalIPv4 address closest to device.
ipv6string⚪ OptionalIP address closest to device as IPv6.
dpidmd5 / dpidsha1string⚪ OptionalDeprecated as of OpenRTB 2.6.Sent when present in the ad request. Kept for DSPs that still read them.
didmd5 / didsha1string⚪ OptionalDeprecated as of OpenRTB 2.6.
geoobject🔴 RequiredLocation of the device assumed to be the user’s current location, defined by a Geo object.country, region, city, zip, lat, lon, type always; metro, accuracy, ipservice, utcoffset when available.
User (2 fields, 1 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredExchange-specific ID for the user.Brand+ user ID.
eidsobject array⚪ OptionalDetails for support of a standard protocol for multiple third party identity providers.Sent only to DSPs set up to receive extended IDs. Also sent as user.ext.eids.
Source (4 fields, 4 required)
FieldTypeRequirementWhat it isBrand+ rule
fdinteger🔴 RequiredEntity responsible for the final impression sale decision, where 0 = exchange, 1 = upstream source.
tidstring🔴 RequiredTransaction ID that must be common across all participants in this bid request.
pchainstring🔴 RequiredPayment ID chain string containing embedded syntax described in the TAG payment ID Protocol v1.0.
ext.schain—🔴 Required2.5 location of the IAB SupplyChain object (2.6: source.schain).Supply chain with the Brand+ node appended, sent as a JSON-encoded string. Also sent as ext.schain at the top level.
Regs (3 fields, 2 required)
FieldTypeRequirementWhat it isBrand+ rule
coppainteger🔴 RequiredFlag indicating if this request is subject to the COPPA regulations established by the USA FTC, where 0 = no, 1 = yes.
gpp / gpp_sidstring / integer array⚪ OptionalThe Global Privacy Platform’s consent string, and the section(s) that apply.
ext.gdpr / ext.consent / ext.us_privacy—🔴 Required2.5 locations of the IAB regs.gdpr, user.consent and regs.us_privacy fields.gdpr and consent always; us_privacy when available.

Back to top

3.3 Bid response

To pass on a request, omit seatbid or return HTTP 204. Brand+ requires VAST in adm; markup on the win notice is not used.

Sample: bid response
{
  "id": "b1b2c3d4000000000000000000000001",
  "bidid": "dsp-response-0001",
  "seatbid": [
    {
      "seat": "<DSP_SEAT_ID>",
      "bid": [
        {
          "id": "dsp-bid-0001",
          "impid": "b1b2c3d4-0000-0000-0000-000000000002",
          "price": 12.5,
          "adid": "<CREATIVE_ID>",
          "nurl": "https://dsp.example/win?price=${AUCTION_PRICE}",
          "burl": "https://dsp.example/bill?price=${AUCTION_PRICE}",
          "adm": "<VAST version=\"3.0\"><Ad id=\"dsp-bid-0001\"><InLine><AdSystem>Example DSP</AdSystem><AdTitle><![CDATA[Example Ad]]></AdTitle><Impression><![CDATA[https://dsp.example/imp]]></Impression><Creatives><Creative><Linear><Duration>00:00:30.000</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"1920\" height=\"1080\" type=\"video/mp4\" bitrate=\"3500\"><![CDATA[https://cdn.dsp.example/ad_1920x1080.mp4]]></MediaFile></MediaFiles></Linear></Creative></Creatives></InLine></Ad></VAST>",
          "adomain": ["advertiser.example"],
          "bundle": "<ADVERTISER_APP_BUNDLE>",
          "iurl": "https://cdn.dsp.example/companion_1280x720.jpeg",
          "cid": "<CAMPAIGN_ID>",
          "crid": "<CREATIVE_ID>",
          "cat": ["IAB9-30"],
          "w": 1280,
          "h": 720,
          "mtype": 2,
          "ext": {}
        }
      ]
    }
  ],
  "cur": "USD"
}

Field reference

Expand an object to see its fields.

Required at a glance: BidResponse.id, BidResponse.seatbid, SeatBid.bid, Bid.id, Bid.impid, Bid.price, Bid.adm

BidResponse (5 fields, 2 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredID of the bid request to which this is a response.Echo the bid request id.
seatbidobject array🔴 Required to bidArray of seatbid objects; 1+ required if a bid is to be made.For no bid, omit or return HTTP 204.
bididstring🔵 RecommendedBidder generated response ID to assist with logging/tracking.
curstring⚪ OptionalBid currency using ISO-4217 alpha codes.Use USD.
nbrinteger⚪ OptionalReason for not bidding. Refer to List: No-Bid Reason Codes in OpenRTB 3.0.
SeatBid (3 fields, 1 required)
FieldTypeRequirementWhat it isBrand+ rule
bidobject array🔴 RequiredArray of 1+ Bid objects, each related to an impression.
seatstring⚪ OptionalID of the buyer seat on whose behalf this bid is made.Required when the deal restricts seats (wseat).
groupinteger⚪ Optional0 = impressions can be won individually; 1 = impressions must be won or lost as a group.
Bid (24 fields, 4 required)
FieldTypeRequirementWhat it isBrand+ rule
idstring🔴 RequiredBidder generated bid ID to assist with logging/tracking.
impidstring🔴 RequiredID of the Imp object in the related bid request.
pricefloat🔴 RequiredBid price expressed as CPM although the actual transaction is for a unit impression only.USD CPM, at or above the floor.
admstring🔴 RequiredOptional means of conveying ad markup in case the bid wins; supersedes the win notice if markup is included in both.Brand+ requires VAST in adm; markup on the win notice is not used. Brand+ reads VAST version, companions and duration from it.
dealidstring⚪ OptionalReference to the deal.id from the bid request if this bid pertains to a private marketplace direct deal.Required when bidding on a deal.
adomainstring array🔵 RecommendedAdvertiser domain for block list checking.Used for advertiser blocking.
cridstring🔵 RecommendedCreative ID to assist with ad quality checking.
cidstring🔵 RecommendedCampaign ID to assist with ad quality checking.
catstring array🔵 RecommendedIAB Tech Lab content categories of the creative. The taxonomy is defined by the cattax field.
cattaxinteger🔵 RecommendedThe taxonomy in use. Refer to List: Category Taxonomies.
nurlstring🔵 RecommendedWin notice URL called by the exchange if the bid wins (not necessarily indicative of a delivered, viewed, or billable ad).
burlstring🔵 RecommendedBilling notice URL called by the exchange when a winning bid becomes billable based on exchange-specific business policy.
lurlstring⚪ OptionalLoss notice URL called by the exchange when a bid is known to have been lost.
durinteger🔵 RecommendedDuration of the video or audio creative in seconds.Used when the VAST has no duration, and for pods.
mtypeinteger🔵 RecommendedType of the creative markup: 1 = Banner, 2 = Video, 3 = Audio, 4 = Native.Use 2 for video.
slotinpodinteger⚪ OptionalIndicates that the bid response is only eligible for a specific position within a video or audio ad pod.
adidstring⚪ OptionalID of a preloaded ad to be served if the bid wins.
iurlstring⚪ OptionalURL without cache-busting to an image that is representative of the content of the campaign, for ad quality/safety checking.
bundlestring⚪ OptionalThe store ID of the app in an app store.
attrinteger array⚪ OptionalSet of attributes describing the creative. Refer to List: Creative Attributes in AdCOM 1.0.
apisinteger array⚪ OptionalList of supported APIs for the markup. If an API is not explicitly listed, it is assumed to be unsupported.
w / hinteger⚪ OptionalWidth and height of the creative in device-independent pixels (DIPS).
expinteger⚪ OptionalAdvisory as to the number of seconds the bidder is willing to wait between the auction and the actual impression.
ext.imptrackers (Verve ext)—⚪ OptionalVerve extension.Brand+ fires these on impression.

Back to top


4. Ad pods

A pod is one ad break filled with several ads. Publishers describe the whole break in one ad request; Brand+ auctions each slot separately and returns the winning ads together.

flowchart LR
    R["Ad request<br/>one impression<br/>podid, poddur, maxseq"] --> B["Brand+<br/>splits into slots"]
    B --> S1["Slot 1<br/>2.5 bid request"]
    B --> S2["Slot 2<br/>2.5 bid request"]
    B --> S3["Slot 3<br/>2.5 bid request"]
    S1 --> D["DSPs"]
    S2 --> D
    S3 --> D
    D -.-> A["Ad response<br/>one Bid per winning ad<br/>with podid and dur"]

How Brand+ reads your pod

You sendBrand+ creates
maxseqThat many slots, up to 20. Larger pods are cut to 20, not rejected.
poddur without maxseq5 slots
Neither1 slot
Missing valueBrand+ assumes
Pod duration (poddur)120 seconds
A slot’s maximum ad duration (maxduration)31 seconds

Slot floor: Brand+ uses the first of these that you send:

  1. imp.bidfloor
  2. the lowest durfloors band that overlaps the slot’s durations
  3. mincpmpersec × the slot’s shortest ad duration

Where both are sent, native 2.6 pod fields take precedence over their ext equivalents.

Pod fields by version

Pod detailOpenRTB 2.6OpenRTB 2.5
Identify the podimp.video.podid on every impression in the breakimp.video.ext.podid on every impression in the break
Dynamic pod length and ad countmaxseq and poddurimp.video.ext.maxseq and imp.video.ext.poddur
Ad durationsminduration and maxduration, or rqddurs for exact durationsminduration and maxduration
Pod position in the contentpodseqimp.video.ext.podseq
Optionalslotinpod, mincpmpersec, durfloorsimp.video.ext.slotinpod, ext.mincpmpersec, ext.durfloors. Use 2.6 for these.

What DSPs receive

One OpenRTB 2.5 bid request per slot, with the slot’s duration limits and floor. Pod fields are in imp.video.ext: podid and sequence on every slot (sequence also as imp.video.sequence), and slotinpod, podseq, rqddurs, mincpmpersec and durfloors only when the publisher sent them. poddur and maxseq are never sent to DSPs. When the request has rqddurs, the outgoing minduration and maxduration narrow to its lowest and highest values.

What publishers get back

Each winning ad is a separate Bid on the impression it fills, carrying podid and dur. In a dynamic pod, all winning ads share that impression’s impid. 2.6 publishers get bid.podid and bid.ext.podid; 2.5 publishers get bid.ext.podid only. dur is also sent as bid.ext.duration; both are left out when neither the bid nor its VAST gives a duration. slotinpod comes back only where the request stated a slot.

[!WARNING]
Check dur before placing an ad. Brand+ ranks bids in a slot by price per second rather than total price, and can move a runner-up into a slot that received no bids. It doesn’t reject a bid whose duration is outside the slot’s limits, doesn’t order the ads, and doesn’t keep same-advertiser ads out of adjacent slots. Your ad server places the winning ads in the break.

Back to top


5. Where fields go in 2.5 vs 2.6

SignalOpenRTB 2.5OpenRTB 2.6

| Version header | x-openrtb-version: 2.5 | x-openrtb-version: 2.6 |
| Supply chain | source.ext.schain | source.schain |
| Extended IDs | user.ext.eids | user.eids |
| GDPR consent string | user.ext.consent | user.consent |
| GDPR flag | regs.ext.gdpr | regs.gdpr |
| US privacy string | regs.ext.us_privacy | regs.us_privacy |
| Network name | app.content.ext.network | app.content.network.name |
| Channel name | app.content.ext.channel | app.content.channel.name |
| Inventory partner domain | app.ext.inventorypartnerdomain | app.inventorypartnerdomain (or app.ext) |
| Structured user agent | Not available | device.sua |
| Pod ID | imp.video.ext.podid | imp.video.podid |
| Pod length and ad count | imp.video.ext.poddur, imp.video.ext.maxseq | imp.video.poddur, imp.video.maxseq |
| Pod position in content | imp.video.ext.podseq | imp.video.podseq |
| Exact ad durations | Not available: use minduration and maxduration | imp.video.rqddurs |
| Slot, per-second floor, duration floors | imp.video.ext.slotinpod, ext.mincpmpersec, ext.durfloors | imp.video.slotinpod, mincpmpersec, durfloors |
| Pod ID in the ad response | bid.ext.podid | bid.podid and bid.ext.podid |
| Slot in the ad response | bid.ext.slotinpod | bid.slotinpod and bid.ext.slotinpod |

Back to top


6. Macros and tracking

MacroReplaced with
${AUCTION_PRICE}Clearing price, in the response currency
${AUCTION_MIN_TO_WIN}Minimum bid that would have won
${AUCTION_LOSS}OpenRTB loss reason code
[ERRORCODE]VAST error code, in VAST Error URLs
URLWhen to fire
nurlWhen the bid wins the auction
burlWhen the impression is billable
lurlWhen the bid loses
VAST Impression, Error and tracking URLsAs the video plays, per the VAST standard

Back to top


7. Enum reference

device.devicetype
ValueMeaning
1Mobile/Tablet
2PC
3Connected TV
4Phone
5Tablet
6Connected device
7Set-top box
8Out-of-home
imp.video.plcmt
ValueMeaning
1In-stream
2Accompanying content
3Interstitial
4No content / standalone
imp.video.protocols
ValueMeaning
1VAST 1.0
2VAST 2.0
3VAST 3.0
4VAST 1.0 Wrapper
5VAST 2.0 Wrapper
6VAST 3.0 Wrapper
7VAST 4.0
8VAST 4.0 Wrapper
imp.video.startdelay
ValueMeaning
> 0Mid-roll at that many seconds
0Pre-roll
-1Generic mid-roll
-2Generic post-roll
imp.ssai
ValueMeaning
0Unknown
1All client-side
2Assets stitched server-side, tracking client-side
3All server-side
device.connectiontype
ValueMeaning
0Unknown
1Ethernet
2Wi-Fi
3Cellular (unknown generation)
42G
53G
64G
75G
bid.mtype
ValueMeaning
1Banner
2Video
3Audio
4Native

Back to top


8. Troubleshooting

Publishers and SSPs

My ad request gets HTTP 422

Brand+ rejects the request when regs.coppa is 1, when there’s no usable public IP (device.ip, device.ipv6 and the connection’s IP are all missing, private or reserved), or when the user is under 14.

My request is rejected and I send cur

If you send cur, it must include USD. Add USD or leave cur out.

My 2.5 or 2.6 fields seem to be ignored

Check the x-openrtb-version header. Without it, the request is processed as OpenRTB 2.3. Also check fields are where your version expects them; see 2.5 vs 2.6.

I sent a pod but get only one ad back

Identify the pod with imp.video.podid (2.6) or imp.video.ext.podid (2.5); sequence doesn’t identify a pod. Send maxseq, poddur or both: with neither, the pod has one slot.

An ad is longer than my slot allows

Brand+ doesn’t reject bids for duration. Check bid.dur (or bid.ext.duration) before placing each ad.

Deal IDs are missing from the ad response

Deal ID pass-back is enabled per account. Ask your Verve account manager.

DSPs

We get no traffic from a region

Each region sends only to its own registered endpoint. Register one for every region you want to buy in.

Our bid won but the ad didn’t render

Brand+ requires VAST in bid.adm. Markup returned on the win notice isn’t used.

We don’t see extended IDs (eids)

user.eids is sent only to DSPs set up to receive extended IDs. Ask your account manager.

Our deal bids are rejected

Include dealid when bidding on a deal, include seat when the deal restricts seats with wseat, and bid at or above the floor in USD CPM.

Back to top


9. Glossary

TermMeaning

| Ad pod | One ad break filled with several ads in a row, described in a single ad request. A dynamic pod lets the auction decide how many ads fill the break, up to a total duration (poddur) and ad count (maxseq). |
| AdBreak ID | Your Brand+ (SPX) identifier for an ad placement. Sent in imp.tagid. |
| Brand+ (B+) | Verve’s marketplace for brand and CTV advertising. |
| CPM | Cost per mille: the price for 1,000 impressions. Brand+ prices and floors are USD CPM. |
| CTV | Connected TV: video watched on a TV through an internet-connected device, such as a smart TV, Roku or other streaming player. |
| DSP | Demand-side platform: the system advertisers use to bid on impressions. |
| First-price auction | The highest bidder wins and pays its own bid. Brand+ runs first-price auctions only (at = 1). |
| Floor | The minimum price a bid must meet, set in imp.bidfloor or, for pods, durfloors and mincpmpersec. |
| IFA | Identifier for advertising: the device’s resettable advertising ID, such as Roku’s RIDA or Samsung’s TIFA. Its type goes in device.ext.ifa_type. |
| Inventory partner domain | The domain of the partner whose app-ads.txt authorises selling the app’s inventory. |
| OpenRTB | The IAB Tech Lab protocol for real-time bidding. Brand+ supports versions 2.5 and 2.6. |
| SSAI | Server-side ad insertion: ads are stitched into the video stream on a server rather than played by the device. imp.ssai says where ad events fire. |
| SSP | Supply-side platform: the system publishers use to sell their inventory. |
| Supply chain (schain) | A list of every company that handled the request on its way to the buyer. Brand+ appends its own node before sending to DSPs. |
| tmax | The time, in milliseconds, allowed for a response to a request. |
| VAST | Video Ad Serving Template: the XML format that carries a video ad’s media files and tracking URLs. |
| VAST InLine and Wrapper | An InLine VAST contains the ad itself. A Wrapper VAST points to another VAST elsewhere, adding its own tracking along the way. |

Back to top


Based on the IAB OpenRTB 2.6 specification. Questions: contact your Verve account manager.


Did this page help you?