DCR Germany Video Cloud API: Difference between revisions
From Engineering Client Portal
MichelFodjo (talk | contribs) No edit summary |
MichelFodjo (talk | contribs) Tag: Undo |
||
(19 intermediate revisions by 3 users not shown) | |||
Line 5: | Line 5: | ||
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps. | This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps. | ||
<pre style="color: | <pre style="color: orange"> | ||
PLease note that the Cloud API | PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production! | ||
</pre> | </pre> | ||
Line 43: | Line 43: | ||
*Testing: <code>https://sc-eucert.nmrodam.com/nmapi/v2/</code> | *Testing: <code>https://sc-eucert.nmrodam.com/nmapi/v2/</code> | ||
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide. | During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide. | ||
Line 70: | Line 69: | ||
====Create Session ID==== | ====Create Session ID==== | ||
A unique Session ID <code>[sessionID]</code> must be created upon app launch and provided in the URL. This will allow measurement to occur for the entire duration that a user is within the app. | A unique Session ID <code>[sessionID]</code> must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app. | ||
A Session ID needs to be completely unique so it is recommended to use | A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use. | ||
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088''' | |||
<br> | |||
==== | <syntaxhighlight lang="javascript"> | ||
'''// Create random GUID''' | |||
function buildGUID() { | |||
var UAIDbase62Characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | |||
var UAIDpayloadLength = 29; | |||
function UAIDgetRandom62() { | |||
var r1; | |||
do { | |||
r1 = Math.floor(Math.random() * (16 * 62)); | |||
} while (r1 > 61); | |||
return r1; | |||
} | |||
var uid = ''; | |||
for (var a = 0; a < UAIDpayloadLength; a++) { | |||
uid += UAIDbase62Characters.charAt(UAIDgetRandom62()); | |||
} | |||
var timestamp_ms = new Date().getTime(); | |||
uid += String(timestamp_ms).substring(3); | |||
return uid; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
Upon exiting the app, the session will need to be terminated using the delete event. <br> | |||
Sessions will automatically expire after 30 minutes of cloud inactivity. | |||
==== Send EMM Ping ==== | |||
An EMM Ping must be sent using the created unique Session ID <code>[sessionID]</code> upon start of the first stream playback. | An EMM Ping must be sent using the created unique Session ID <code>[sessionID]</code> upon start of the first stream playback. | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
Line 92: | Line 120: | ||
===Configure Payload=== | ===Configure Payload=== | ||
====Description Payload==== | |||
All Cloud API requests must contain the following payload data: | All Cloud API requests must contain the following payload data: | ||
Line 101: | Line 131: | ||
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section. | The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section. | ||
==== Payload Example ==== | |||
The example below should be referenced when following the steps for configuring the request payload. | The example below should be referenced when following the steps for configuring the request payload. | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
// 1. Configure Payload | // 1. Create Session ID using the UUID Generator code provided | ||
// | sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088 // Example sessionID | ||
// 2. Define URL Structure with App ID and Session ID | |||
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b= | |||
// 3. Configure Payload | |||
// 3.1 Configure Payload: devInfo | |||
payload = { | payload = { | ||
"devInfo": { | "devInfo": { | ||
"devId": " | "devId": "", | ||
"apn": "AppName", | "apn": "AppName", | ||
"apv": "1.0" | "apv": "1.0" | ||
}, | }, | ||
// | // 3.2 Configure Payload: metadata | ||
"metadata": { | "metadata": { | ||
"content": { // object for measuring video content | "content": { // object for measuring video content | ||
"type": "content", | "type": "content", | ||
"assetid": " | "assetid": "88675545", | ||
"program": "Program Name", | "program": "Program Name", | ||
"title": " | "title": "episode title", | ||
"length": " | "length": "3600", | ||
// | // custom metadata | ||
"nol_c0": "p0,1", | |||
"nol_c2": "p2,Y", | |||
"nol_c8": | "nol_c7": "p7,videoid123", | ||
"nol_c9": | "nol_c8": "p8,", | ||
"nol_c9": "p9,VideoTitle123", | |||
"nol_c10": "p10,clientname", | "nol_c10": "p10,clientname", | ||
"nol_c12": "p12,Content", | "nol_c12": "p12,Content", | ||
Line 133: | Line 170: | ||
}, | }, | ||
"ad": { | "ad": { | ||
"type": "preroll", | "type": "preroll", | ||
"assetid": " | "assetid": "ad345-67483", | ||
"title": " | "title": "ad_title", | ||
"length": "25", | |||
"nol_c8": "p8, | "nol_c8": "p8,", | ||
"nol_c12": "p12,Werbung" | "nol_c10": "p10,clientname", | ||
"nol_c11": "p11,2352723141", | |||
"nol_c12": "p12,Werbung", | |||
"nol_c17": "p17,preroll" | |||
} | } | ||
}, | }, | ||
// | // 3.3 Configure Payload: events | ||
"event": "playhead", //event name | "event": "playhead", //event name | ||
"position": "300", // position in seconds | "position": "300", // position in seconds | ||
"type": "content", //"content" or "ad" | "type": "content", //"content" or "ad" | ||
"utc": "1456448742000", //unix timestamp in milliseconds | "utc": "1456448742000", //unix timestamp in milliseconds | ||
"sessid": "xxxjavd6wzirm93xb95uxjy1ac5wu1627638609" // unique for each video play | "sessid": "xxxjavd6wzirm93xb95uxjy1ac5wu1627638609" // create and pass a unique sessid for each video play using UUID Generator code provided | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
====Configure Payload: devInfo==== | |||
An object <code>"devInfo"</code> will need to be created to capture App and Device information. | An object <code>"devInfo"</code> will need to be created to capture App and Device information. | ||
Line 158: | Line 198: | ||
! Keys !! Description !! Values !! Required | ! Keys !! Description !! Values !! Required | ||
|- | |- | ||
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) || custom || | | devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || | ||
|- | |- | ||
| apn || app name || custom || ✓ | | apn || app name || custom || ✓ | ||
Line 170: | Line 210: | ||
// create devInfo object | // create devInfo object | ||
"devInfo": { | "devInfo": { | ||
"devId": " | "devId": "", | ||
"apn": "AppName", | "apn": "AppName", | ||
"apv": "1.0" | "apv": "1.0" | ||
Line 182: | Line 222: | ||
===== Content Metadata ===== | ===== Content Metadata ===== | ||
Content metadata should remain constant throughout the | |||
For detailed information | ====== Description of Content metadata ====== | ||
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play. | |||
For detailed information on metadata and custom variables, see '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]''' | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! | ! Keys !! Description !! Values !! Required/Obligatory | ||
|- | |- | ||
| type || type of asset || "content" || ✓ | | type || type of asset || <code>"content"</code> || ✓ | ||
|- | |- | ||
| assetid || unique ID assigned to asset ( | | assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)|| custom (no [[Special Characters]]) || ✓ | ||
|- | |- | ||
| program || (string) name of program ( | | program ||(string) name of program (254 character limit) || custom || ✓ | ||
|- | |- | ||
| title || (string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓ | | title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓ | ||
|- | |- | ||
| length || | | length || length of content in seconds || <code>seconds</code> ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓ | ||
|- | |- | ||
| clientid || | | clientid || | ||
parent ID – value is automatically populated through provided | parent ID – value is automatically populated through provided App ID.<br/> | ||
In order to override the brand configured to the | In order to override the brand configured to the App ID, pass parent <br/> | ||
value here and the sub-brand ID associated | value here and the sub-brand ID associated with that brand in the subbrand <br/> | ||
key (e.g. multiple brands in App) | key (e.g. multiple brands in App) | ||
|| | || | ||
Line 208: | Line 253: | ||
|- | |- | ||
| subbrand || vcid/sub-brand ID – value is automatically populated through provided<br/> | | subbrand || vcid/sub-brand ID – value is automatically populated through provided<br/> | ||
App ID. In order to override the sub-brand configured to the App ID, value can <br/> | |||
be passed here (e.g. multiple sub-brands in App) | be passed here (e.g. multiple sub-brands in App) | ||
|| | || | ||
provided by Nielsen | provided by Nielsen | ||
|| | || | ||
|- | |- | ||
| nol_c0 || number of episode part (Sendungsteilenummer) || | | nol_c0 || number of episode part (Sendungsteilenummer) || number || ✓ | ||
|- | |- | ||
| nol_c2 || web only || 'Y' or 'N' || ✓ | | nol_c2 || web only || 'Y' or 'N' || ✓ | ||
|- | |- | ||
| nol_c5 || page URL || custom || | | nol_c5 || page URL || custom || | ||
Line 227: | Line 268: | ||
| nol_c7 || Video ID || custom || ✓ | | nol_c7 || Video ID || custom || ✓ | ||
|- | |- | ||
| nol_c8 || | | nol_c8 || not in use || leave blank, reserved for AGF || | ||
|- | |- | ||
| nol_c9 || episode title || custom - no backslash allowed in string (because of 3rd party data processing) || ✓ | | nol_c9 || episode title || custom - no backslash allowed in string (because of 3rd party data processing) || ✓ | ||
|- | |- | ||
| nol_c10 || publisher || custom || ✓ | | nol_c10 || publisher || custom || ✓ | ||
|- | |- | ||
| nol_c12 || type of asset || 'Trailer' or 'Content' || ✓ | | nol_c12 || type of asset || 'Trailer' or 'Content' || ✓ | ||
|- | |- | ||
| nol_c13 || | | nol_c13 || custom variable || custom || | ||
|- | |- | ||
| nol_c14 || | | nol_c14 || not in use || leave blank, reserved for AGF || | ||
|- | |- | ||
| nol_c15 || format ID || custom || | | nol_c15 || format ID || custom || | ||
|- | |- | ||
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc || | | nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc || | ||
|- | |- | ||
| nol_c18 || livestream || 'Y' or 'N' || ✓ | | nol_c18 || livestream || 'Y' or 'N' || ✓ | ||
|- | |- | ||
| nol_c19 || custom variable || custom || | | nol_c19 || custom variable || custom || | ||
|- | |- | ||
| nol_c20 || GfK-ID | | nol_c20 || GfK-ID || custom || | ||
|} | |} | ||
<br /> | |||
====== Example Content metadata ====== | |||
<syntaxhighlight lang='json'>// create content object | <syntaxhighlight lang='json'>// create content object | ||
"content": { | "content": { | ||
"type": "content", | "type": "content", | ||
"assetid": " | "assetid": "88675545", | ||
"program": "Program Name", | "program": "Program Name", | ||
"title": " | "title": "episode title", | ||
"length": " | "length": "3600", | ||
// | // custom metadata | ||
"nol_c0": "p0,1", | |||
"nol_c2": "p2,Y", | |||
"nol_c8": | "nol_c7": "p7,videoid123", | ||
"nol_c9": | "nol_c8": "p8,", | ||
"nol_c9": "p9,VideoTitle123", | |||
"nol_c10": "p10,clientname", | "nol_c10": "p10,clientname", | ||
"nol_c12": "p12,Content", | "nol_c12": "p12,Content", | ||
Line 274: | Line 313: | ||
===== Ad Metadata (optional for public broadcasters) ===== | ===== Ad Metadata (optional for public broadcasters) ===== | ||
====== Description of Ad metadata ====== | |||
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins. | The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins. | ||
For detailed information on metadata and custom variables, see '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]''' | |||
<br/> | <br/> | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 282: | Line 324: | ||
| type || type of ad || 'preroll', 'midroll', or 'postroll' || ✓ | | type || type of ad || 'preroll', 'midroll', or 'postroll' || ✓ | ||
|- | |- | ||
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations) || custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) || ✓ | | assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)|| custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) || ✓ | ||
|- | |||
| subbrand || vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen || | |||
|- | |- | ||
| title || only the AD-ID is necessary || custom, <AD-ID> without "VAST" Prefix or other, i.e. '2352723141' || ✓ | | title || only the AD-ID is necessary || custom, <AD-ID> without "VAST" Prefix or other, i.e. '2352723141' || ✓ | ||
|- | |||
| length || length of Ad in seconds || length of Ad in seconds || ✓ | |||
|- | |- | ||
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' || | | nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' || | ||
Line 292: | Line 338: | ||
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' || | | nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' || | ||
|- | |- | ||
| nol_c8 || | | nol_c8 || not in use || leave blank, reserved for AGF || | ||
|- | |- | ||
| nol_c10 || publisher || custom || ✓ | | nol_c10 || publisher || custom || ✓ | ||
Line 302: | Line 348: | ||
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc || | | nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc || | ||
|- | |- | ||
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or ' | | nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' || ✓ | ||
|} | |} | ||
===== Example Ad | ====== Example Ad metadata ====== | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
// create ad object | // create ad object | ||
"ad": { | "ad": { | ||
"type": "preroll", | "type": "preroll", | ||
"assetid": " | "assetid": "ad345-67483", | ||
"title": " | "title": "ad_title", | ||
"length": "25", | |||
"nol_c8": "p8, | "nol_c8": "p8,", | ||
"nol_c12": "p12,Werbung" | "nol_c10": "p10,clientname", | ||
"nol_c11": "p11,2352723141", | |||
"nol_c12": "p12,Werbung", | |||
"nol_c17": "p17,preroll" | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Configure Payload: Events === | ==== Configure Payload: Events ==== | ||
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below. | The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below. | ||
==== Event Types ==== | ===== Event Types ===== | ||
The available events are: | The available events are: | ||
Line 485: | Line 535: | ||
*Wi-Fi OFF / ON | *Wi-Fi OFF / ON | ||
*App Crash or Exit | *App Crash or Exit | ||
Line 498: | Line 547: | ||
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration. | Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration. | ||
see '''[[#Payload Example|Payload Example]]''' | |||
// Append payload to URL | // Append payload to URL | ||
Line 563: | Line 563: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Enable Debug Logging === | |||
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification. | Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification. | ||
Line 612: | Line 612: | ||
In order to start live stream select the checkbox "isLive" in the <code>Playback Settings</code> below the video player. | In order to start live stream select the checkbox "isLive" in the <code>Playback Settings</code> below the video player. | ||
Start the Reference Implementation for | Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI]. | ||
<blockquote> | <blockquote> | ||
Review the Nielsen CloudAPI Call Sequence below the Video Player. | Review the Nielsen CloudAPI Call Sequence below the Video Player. | ||
Line 619: | Line 619: | ||
== Disclose Nielsen Privacy Statement == | == Disclose Nielsen Privacy Statement == | ||
The Cloud API | The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain. | ||
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy: | In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy: | ||
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data. | A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data. | ||
A link to the Nielsen Digital Measurement Privacy Policy located at https:// | A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de . | ||
== Testing == | == Testing == |
Latest revision as of 11:37, 27 August 2024
DCR Integration Utilizing Cloud API
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!
Prerequisites
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.
Item | Description | Source |
---|---|---|
App ID (appid) | Unique ID assigned to the player/site and configured by product. | Provided by Nielsen |
Integration
We will cover the steps for constructing the Cloud API Calls.
URL Structure
The Cloud API Calls are HTTP GET Requests with the URL structure:
[endpoint]/[appid]/[sessionID]/a?b=[payload]
The URL includes the following components:
[endpoint]
: location of data collection environment[appid]
: provided App ID.
Note:The "P" prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be :[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]
[sessionID]
: unique value for each user session[payload]
: metadata and events
Endpoint
There are endpoints for testing and production:
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.
URL Example
As you move through the integration steps, you can reference the below URL structure with the expanded payload:
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=
{
"devInfo": [deviceInfo],
"metadata": {
"content": [content_metadata],
"ad": [ad metadata]
},
"event": [event],
"position": [playhead_position],
"type": [asset type],
"utc": [Unix time in ms],
"sessid": [unique view session ID for each video play]
}
Create Session ID and send EMM Ping
Create Session ID
A unique Session ID [sessionID]
must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see Reference Implementation for VoD and Live Streams for your reference and use.
Session ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088
'''// Create random GUID'''
function buildGUID() {
var UAIDbase62Characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var UAIDpayloadLength = 29;
function UAIDgetRandom62() {
var r1;
do {
r1 = Math.floor(Math.random() * (16 * 62));
} while (r1 > 61);
return r1;
}
var uid = '';
for (var a = 0; a < UAIDpayloadLength; a++) {
uid += UAIDbase62Characters.charAt(UAIDgetRandom62());
}
var timestamp_ms = new Date().getTime();
uid += String(timestamp_ms).substring(3);
return uid;
}
Upon exiting the app, the session will need to be terminated using the delete event.
Sessions will automatically expire after 30 minutes of cloud inactivity.
Send EMM Ping
An EMM Ping must be sent using the created unique Session ID [sessionID]
upon start of the first stream playback.
https://[sessionID].uaid.nmrodam.com/
Also see Reference Implementation for VoD and Live Streams for your reference.
Create View Session ID for each Video Start
An View Session ID [sessid]
must be created upon start of each stream playback, sessid is unique per video play.
Define URL Structure
Define the URL structure using your provided [appid]
and a unique [sessionID]
.
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]
Configure Payload
Description Payload
All Cloud API requests must contain the following payload data:
- devInfo: device and app info
- metadata: asset metadata
- event metadata: type of event
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.
Payload Example
The example below should be referenced when following the steps for configuring the request payload.
// 1. Create Session ID using the UUID Generator code provided
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088 // Example sessionID
// 2. Define URL Structure with App ID and Session ID
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=
// 3. Configure Payload
// 3.1 Configure Payload: devInfo
payload = {
"devInfo": {
"devId": "",
"apn": "AppName",
"apv": "1.0"
},
// 3.2 Configure Payload: metadata
"metadata": {
"content": { // object for measuring video content
"type": "content",
"assetid": "88675545",
"program": "Program Name",
"title": "episode title",
"length": "3600",
// custom metadata
"nol_c0": "p0,1",
"nol_c2": "p2,Y",
"nol_c7": "p7,videoid123",
"nol_c8": "p8,",
"nol_c9": "p9,VideoTitle123",
"nol_c10": "p10,clientname",
"nol_c12": "p12,Content",
"nol_c18": "p18,N"
},
"ad": {
"type": "preroll",
"assetid": "ad345-67483",
"title": "ad_title",
"length": "25",
"nol_c8": "p8,",
"nol_c10": "p10,clientname",
"nol_c11": "p11,2352723141",
"nol_c12": "p12,Werbung",
"nol_c17": "p17,preroll"
}
},
// 3.3 Configure Payload: events
"event": "playhead", //event name
"position": "300", // position in seconds
"type": "content", //"content" or "ad"
"utc": "1456448742000", //unix timestamp in milliseconds
"sessid": "xxxjavd6wzirm93xb95uxjy1ac5wu1627638609" // create and pass a unique sessid for each video play using UUID Generator code provided
}
Configure Payload: devInfo
An object "devInfo"
will need to be created to capture App and Device information.
Keys | Description | Values | Required |
---|---|---|---|
devId | unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF | custom | |
apn | app name | custom | ✓ |
apv | app build version | custom | ✓ |
Example devInfo Object
// create devInfo object
"devInfo": {
"devId": "",
"apn": "AppName",
"apv": "1.0"
},
3.2 Configure Payload: metadata
Asset metadata can be passed through "metadata"
. There are two asset types: "content"
for video and "ad"
for ads. The metadata received for each asset is used for classification and reporting.
You will need to set up "metadata"
objects for "content"
and "ad"
with the required Nielsen keys as shown in the sample code below.
Content Metadata
Description of Content metadata
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.
For detailed information on metadata and custom variables, see AGF Metadata Convention for Video Measurement
Keys | Description | Values | Required/Obligatory |
---|---|---|---|
type | type of asset | "content" |
✓ |
assetid | unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations) | custom (no Special Characters) | ✓ |
program | (string) name of program (254 character limit) | custom | ✓ |
title | (string) episode title (max 254 characters) | custom - no backslash allowed in string (because of 3rd party data processing) | ✓ |
length | length of content in seconds | seconds ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) |
✓ |
clientid |
parent ID – value is automatically populated through provided App ID. |
provided by Nielsen |
|
subbrand | vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can |
provided by Nielsen |
|
nol_c0 | number of episode part (Sendungsteilenummer) | number | ✓ |
nol_c2 | web only | 'Y' or 'N' | ✓ |
nol_c5 | page URL | custom | |
nol_c7 | Video ID | custom | ✓ |
nol_c8 | not in use | leave blank, reserved for AGF | |
nol_c9 | episode title | custom - no backslash allowed in string (because of 3rd party data processing) | ✓ |
nol_c10 | publisher | custom | ✓ |
nol_c12 | type of asset | 'Trailer' or 'Content' | ✓ |
nol_c13 | custom variable | custom | |
nol_c14 | not in use | leave blank, reserved for AGF | |
nol_c15 | format ID | custom | |
nol_c16 | content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) | custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc | |
nol_c18 | livestream | 'Y' or 'N' | ✓ |
nol_c19 | custom variable | custom | |
nol_c20 | GfK-ID | custom |
Example Content metadata
// create content object
"content": {
"type": "content",
"assetid": "88675545",
"program": "Program Name",
"title": "episode title",
"length": "3600",
// custom metadata
"nol_c0": "p0,1",
"nol_c2": "p2,Y",
"nol_c7": "p7,videoid123",
"nol_c8": "p8,",
"nol_c9": "p9,VideoTitle123",
"nol_c10": "p10,clientname",
"nol_c12": "p12,Content",
"nol_c18": "p18,N"
}
Ad Metadata (optional for public broadcasters)
Description of Ad metadata
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins. For detailed information on metadata and custom variables, see AGF Metadata Convention for Video Measurement
Keys | Description | Values | Required |
---|---|---|---|
type | type of ad | 'preroll', 'midroll', or 'postroll' | ✓ |
assetid | unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations) | custom (no SPACE - no Special Characters) | ✓ |
subbrand | vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) | provided by Nielsen | |
title | only the AD-ID is necessary | custom, <AD-ID> without "VAST" Prefix or other, i.e. '2352723141' | ✓ |
length | length of Ad in seconds | length of Ad in seconds | ✓ |
nol_c1 | universal AdID (Additional AD-ID to be used by second or third marketers) | custom, i.e. 'adgapid_022_800160_1601097_001_0_0' | |
nol_c2 | web only | 'Y' or 'N' | |
nol_c4 | form of advertising | 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' | |
nol_c8 | not in use | leave blank, reserved for AGF | |
nol_c10 | publisher | custom | ✓ |
nol_c11 | AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) | custom, i.e. '2352723141' | ✓ |
nol_c12 | content type (key distinction of content, advertising, and Trailer) | 'Werbung' | ✓ |
nol_c16 | content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) | custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc | |
nol_c17 | ad placement type (placement information of advertisement) | 'preroll', 'midroll', 'postroll' or 'other' | ✓ |
Example Ad metadata
// create ad object
"ad": {
"type": "preroll",
"assetid": "ad345-67483",
"title": "ad_title",
"length": "25",
"nol_c8": "p8,",
"nol_c10": "p10,clientname",
"nol_c11": "p11,2352723141",
"nol_c12": "p12,Werbung",
"nol_c17": "p17,preroll"
}
Configure Payload: Events
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.
Event Types
The available events are:
Event | Description |
---|---|
"playhead" |
Handling PlayheadCalling General
Live Stream
VoD Stream
End of an Asset
Ads
User Actions
|
"complete" |
The complete event must be sent when the content has completed full playback. Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries. |
"delete" |
The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads). |
Event Parameters
The following parameters need to be passed when calling events:
Parameter | Description | Value | Required |
---|---|---|---|
"event" |
event type | "playhead" , "complete" , or "delete" |
✓ |
"position" |
playhead position in seconds or Unix time in seconds | "300" |
✓ |
"type" |
asset type | "content" , "ad" |
✓ |
"utc" |
Unix timestamp in milliseconds. Must be passed every 10 seconds. | "1472760000000" |
✓ |
"sessid" |
Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. | "xxxjavd6wzirm93xb95uxjy1ac5wu1627638609" |
✓ |
Example Event
You can call events by passing values in the required parameters:
"devInfo": [deviceInfo],
"metadata": {
"content": [content metadata],
"ad": [ad metadata]
},
// Event Parameters
"event": [event], // event name
"position": [playheadPosition], //position in seconds
"type": [asset type], // values are "content" or "ad"
"utc": "1472760000000", //unix timestamp in milliseconds
"sessid": "xxxjavd6wzirm93xb95uxjy1ac5wu1627638609", // unique for each video play
}
Note: The full payload including "devInfo" and "metadata" must be populated in each event request.
Sample Event Lifecycle for VoD Stream
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.
// Start of Session: session ID created when App is opened
// Preroll
Ad Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472760000000"}
// Content
Content Playhead {"event": "playhead", "position": "0", "type": "content", "utc": "1472760000000"}
// Midroll
Midroll Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472760000000"}
// Content resumes at 15 minutes
Content Playhead {"event": "playhead", "position": "900", "type": "content", "utc": "1472760000000"}
// Content completes at 30 minutes
Complete {"event": "complete", "position": "1800", "type": "content", "utc": "1472760000000"}
// Postroll
Ad Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472760000000"}
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.
Delete { "event": "delete", "position": "", "type": "", "utc": "1472760000000"}
Sample Event Lifecycle for VoD Stream - Detailed Storyline
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.
// SESSION STARTS
// Start of Session: session ID created when App is opened
// PREROLL
// Preroll Start - Start each Ad with a position of "0", resetting to '0' for each Ad, and Ad break.
Ad Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472760000000"}
// Preroll Stop - End each Ad with the final position of the Ad.
Ad Playhead {"event": "playhead", "position": "15", "type": "ad", "utc": "1472761500000"}
// CONTENT
// Content Start - Start new content streams with a position of "0" incrementing the position every 10 seconds.
Content Playhead {"event": "playhead", "position": "0", "type": "content", "utc": "1472761500000"}
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.
Content Playhead {"event": "playhead", "position": "299", "type": "content", "utc": "1472787400000"}
// MIDROLL
// Midroll Start - Start each Ad with a position of "0", resetting to '0' for each Ad, and Ad break.
Midroll Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472787500000"}
// Midroll Stop - End each Ad with the final position of the Ad.
Ad Playhead {"event": "playhead", "position": "60", "type": "ad", "utc": "1472793500000"}
// CONTENT
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.
Content Playhead {"event": "playhead", "position": "300", "type": "content", "utc": "1472799500000"}
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.
Final Content Playhead {"event": "playhead", "position": "612", "type": "content", "utc": "1472830700000"}
Complete {"event": "complete", "position": "612", "type": "content", "utc": "1472830800000"}
// POSTROLL
// Postroll Start - Start each Ad with a position of "0", resetting to '0' for each Ad, and Ad break.
Ad Playhead {"event": "playhead", "position": "0", "type": "ad", "utc": "1472830900000"}
// Postroll Stop - End each Ad with the final position of the Ad.
Ad Playhead {"event": "playhead", "position": "45", "type": "ad", "utc": "1472835300000"}
// SESSION ENDS
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.
Delete { "event": "delete", "position": "", "type": "", "utc": "1472835400000"}
Interruption Scenarios
As part of configuring events, you will need to handle all possible interruption scenarios such as:
- Wi-Fi OFF / ON
- App Crash or Exit
When playback is interrupted, the app needs to send delete immediately.
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.
Note: The session will automatically timeout after 30 minutes of inactivity.
Example Request
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.
see Payload Example
// Append payload to URL function sendPayloadToNielsen() {
var payloadStr = JSON.stringify(payload); // payload as string var imgPing = new Image(); imgPing.onload = function() { // onload event, payload succesfull sent }; imgPing.onerror = function() { // handle error i.e. wait and send again }; imgPing.src = sessionURL+encodeURIComponent(payloadStr);
} </syntaxhighlight>
Enable Debug Logging
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.
GET Request
Display GET Request to console using a name to identify each event (e.g. playhead).
console.log("Event", image);
Payload
Output payload to identify required metadata and events.
console.log("Event Payload", payload);
HTTP Response Code
Confirm request was completed by viewing HTTP response code.
code = msg.GetResponseCode();
console.log("Response Code", code);
You can reference the HTTP Response Code table when reviewing your requests:
Status Code | Status Text | Description |
---|---|---|
200 |
OK | request received |
403 |
Forbidden | invalid App ID |
404 |
Not Found | JSON issue |
Review the Reference Implementation for VoD and Live Streams
The Reference Implementation covers vod and Live use cases. It also covers DAI (Dynamic Ad Insertion) with preroll and postroll Ads.
In order to start live stream select the checkbox "isLive" in the Playback Settings
below the video player.
Start the Reference Implementation for AGF by selection Germany in the country dropbox RefImplCloudAPI.
Review the Nielsen CloudAPI Call Sequence below the Video Player.
Disclose Nielsen Privacy Statement
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data. A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .
Testing
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.
Payload Validation
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:
- devInfo
- Asset metadata for both content, and ads
- Events
Player Events
Review event calls:
playhead
- Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.
- Final playhead position is sent on content, or ad before switching between assets.
- Content metadata remains constant throughout an episode, or clip play.
- Ad metadata is populated appropriately for each individual ad.
- Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.
- For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.
- Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.
- Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.
complete
- Check that the complete event executes upon content complete after the final playhead update is sent
- Do not execute the complete event for ads
delete
- Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.
GET Request Format
- Ensure that the event payloads are formatted in JSON
- Check to see that each of the Cloud API GET requests are properly encoded
HTTP Response
- Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.
Go Live
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.
Change Endpoint: You will need to update to the production endpoint:
- Testing:
https://sc-eucert.nmrodam.com/nmapi/v2/
- Production:
https://???.nmrodam.com/nmapi/v2/
Your production URL structure should now be:
https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]
Disable Logging: You can now disable debug logging