The Google DAI Pod Serving API lets you perform server-side ad insertion powered by Google Ads while maintaining control of your own video stitching.
This guide shows you how to interact with the Pod Serving API and achieve similar functionality with the IMA DAI SDK. For specific questions about supported functionality, contact your Google account manager.
The Pod Serving API supports pod serving streams in either HLS or MPEG-DASH streaming protocols. This guide focuses on HLS streams and highlights the key differences between HLS and MPEG-DASH in specific steps.
To integrate the Pod Serving API into your app for VOD streams, complete the following steps:
Make a stream registration request to Ad Manager
Make a POST request to the stream registration endpoint. You receive in turn a JSON response containing the stream ID to send to your manifest manipulation server and associated Pod Serving API endpoints.
API endpoint
POST:/ondemand/pods/api/v1/network/{network_code}/stream_registration
Host: dai.google.com
Content-Type: application/json
Path parameters
{network_code}
JSON body parameters
targeting_parameters
Response JSON
media_verification_url
|
The base URL to ping playback tracking events. A complete media verification URL is formed by appending an ad event ID to this base URL. |
metadata_url
|
The URL to request ad pod metadata . |
stream_id
|
The string used to identify the current stream session. |
valid_for
|
The amount of time left until the current stream session expires, in dhms
(days, hours, minutes, seconds) format. For example, 2h0m0.000s
represents a duration of 2 hours. |
valid_until
|
The time at which the current stream session expires, as an ISO 8601
datetime string in yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm
format. |
Example request (cURL)
curl
-X
POST
\
-d
'{"targeting_parameters":{"url":"http://example.com"}}'
\
-H
'Content-Type: application/json'
\
https://dai.google.com/ondemand/pods/api/v1/network/21775744923/stream_registration
Example response
{
"media_verification_url"
:
"https://dai.google.com/.../media/"
,
"metadata_url"
:
"https://dai.google.com/.../metadata"
,
"stream_id"
:
"6e69425c-0ac5-43ef-b070-c5143ba68541:CHS"
,
"valid_for"
:
"8h0m0s"
,
"valid_until"
:
"2023-03-24T08:30:26.839717986-07:00"
}
In case of errors, standard HTTP error codes are returned with no JSON response body.
Parse the JSON response and store the relevant values.
Request the stream manifest from the manifest manipulator
Each manifest manipulator has a different request and response formats. Contact your manipulator provider to understand their specific requirements. If you're implementing your own manifest manipulator, read the manifest manipulator guide to understand the requirements for this component.
In general, you need to pass the stream ID that was returned by the registration endpoint above to your manifest manipulator for it to build session-specific manifests. Unless explicitly stated by your manifest manipulator, the response to your manifest request is a video stream containing both content and ads.
Example request (cURL)
curl
https:// {
manifest_manipulator }
/video/1331997/stream/6e69425c-0ac5-43ef-b070-c5143ba68541:CHS/vod_manifest.m3u8
Example response (HLS)
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs0",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="abcd1234_ subitles-en.vtt"
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.42e00a,mp4a.40.2"
abcd1234_video-1080p.m3u8
Play the stream
Load the manifest that you received from the manifest manipulation server into a video player and start the playback.
Request ad pod metadata from Ad Manager
Make a GET
request to the metadata_url
that you received in step one. This
step must occur after you've received the stitched manifest from your manifest
manipulator. In return, you receive a JSON object containing the following
parameters:
tags
progress
, the full ad event ID. Each value is an object containing the following parameters:
ad
ads
object.ad_break_id
ad_breaks
object.type
start
|
Fired at the beginning of the ad. |
firstquartile
|
Fired at the end of the first quartile. |
midpoint
|
Fired at the midpoint of the ad. |
thirdquartile
|
Fired at the end of the third quartile. |
complete
|
Fired at the end of the ad. |
progress
|
Fired periodically throughout the ad, to notify the app that an ad break is playing. |
ads
tags
object
listed above. Each value is an object containing the following parameters: ad_break_id
|
The ID of an ad break that matches a key in the ad_breaks
object. |
position
|
The position at which this ad appears within the set of ads in the ad break, in floating point seconds. |
duration
|
The length of the ad in floating point seconds. |
clickthrough_url
|
The URL that should open when a user interacts with this ad, if supported. |
ad_breaks
tags
and ads
objects listed above. Each value is an object
containing the following parameters: type
|
The type of ad break. Ad break types are pre
(pre-roll), mid
(mid-roll), and post
(post-roll). |
duration
|
The length of the ad break in floating point seconds. |
ads
|
The number of ads in this ad break. |
Store these values to associate with timed metadata events within your video stream.
Example request (cURL)
curl
https://dai.google.com/.../metadata
Example response
{
"tags"
:{
"google_5555555555"
:{
"ad"
:
"0000229834_ad1"
,
"ad_break_id"
:
"0000229834"
,
"type"
:
"firstquartile"
},
"google_1234567890123456789"
:{
"ad"
:
"0000229834_ad1"
,
"ad_break_id"
:
"0000229834"
,
"type"
:
"progress"
},
...
},
"ads"
:{
"0000229834_ad1"
:{
"ad_break_id"
:
"0000229834"
,
"position"
:
1
,
"duration"
:
15
,
"clickthrough_url"
:
"https://.../"
,
...
},
...
},
"ad_breaks"
:{
"0000229834"
:{
"type"
:
"mid"
,
"duration"
:
15
,
"ads"
:
1
},
...
}
}
Listen for ad events
Listen for timed metadata through triggered ad events in the audio/video stream of your video player.
For MPEG-TS streams, the metadata appears as in-band ID3 v2.3 tags. Each
metadata tag has the ID TXXX
, and the value begins with the string google_
followed by a series of characters. This value is the ad event ID
.
The XXX
in TXXX
is not a placeholder. The string TXXX
is the ID3 tag ID
reserved for "user defined text".
Example ID3 tag
TXXXgoogle_1234567890123456789
For MP4 streams, these are sent as in-band emsg events that emulate ID3 v2.3
tags. Each relevant emsg box has a scheme_id_uri
value of either https://aomedia.org/emsg/ID3
or https://developer.apple.com/streaming/emsg-id3
and a message_data
value
beginning with ID3TXXXgoogle_
. This message_data
value, without the ID3TXXX
prefix, is the ad event ID
.
Example emsg box
The data structure could vary, depending on your media player library.
If the ad event ID is google_1234567890123456789
the response looks like
this:
{
"scheme_id_uri"
:
"https://developer.apple.com/streaming/emsg-id3"
,
"presentation_time"
:
27554
,
"timescale"
:
1000
,
"message_data"
:
"ID3TXXXgoogle_1234567890123456789"
,
...
}
Some media player libraries automatically present emsg events that emulate ID3 tags as native ID3 tags. In this case, MP4 streams present identical ID3 tags as MPEG_TS.
Update the client video player app's UI
Each ad event ID can be matched to a key in the tags
object from step 4.
Matching these values is a two-step process:
-
Check the
tags
object for a key matching the full ad event ID. If a match is found, retrieve the event type and its associatedad
andad_break
objects. These events should have the typeprogress
.If a match is not found for the full ad event ID, check the
tags
object for a key matching the first 17 characters of the ad event ID. Retrieve the event type and the associatedad
andad_break
objects. This should retrieve all events with types other thanprogress
. -
Use this retrieved information to update your player's UI. For example, when you receive a
start
or the firstprogress
event, hide your player's seek controls and display an overlay describing the current ad's position in the ad break, for example: "Ad 1 of 3".
Example ad event IDs
google_1234567890123456789 // Progress event ID google_5555555555123456789 // First Quartile event ID
Example tags object
{
" google_5555555555"
:{
"ad"
:
"0000229834_ad1"
,
"ad_break_id"
:
"0000229834"
,
"type"
:
"firstquartile"
},
"google_1234567890123456789"
:{
"ad"
:
"0000229834_ad1"
,
"ad_break_id"
:
"0000229834"
,
"type"
:
"progress"
},
...
}
Send media verification pings
A media verification ping must be sent to Ad Manager every time an ad event
with a type other than progress
is received.
To generate the complete media verification URL of an ad event, append the full
ad event ID to the media_verification_url
value from the stream registration
response.
Make a GET request with the complete URL. If the verification request is
successful, you receive an HTTP response with status code 202
.
Otherwise, you get the HTTP error code 404
.
Example request (cURL)
curl
https:// {
... }
/media/google_5555555555123456789
Example successful response
HTTP/1.1 202 Accepted