Server guided ad insertion (SGAI) provides an ad pod manifest ready for
stitching on client devices. If you have enabled Pod Serving DAI in your Google
Ad Manager network, you have access to use SGAI. If you don't have Pod Serving
DAI enabled, contact your account manager.

With SGAI, you use the Pod serving API endpoints for creating a stream
retrieving ad metadata and the ad pod manifests.

If you have a manifest manipulation server, you can generate the ad pod
manifest URLs and insert ad markers that carry the ad pod manifest information
in your content stream, according to your preferred specification.

Alternatively, you can schedule an ad break using a different mechanism other
than the ad markers in the stream manifest. In these cases, your app can listen
to other events, for example, user interaction with the stream, the app itself,
or a push notification. After these events, the app can generate the ad
pod manifest URLs and tell the player to begin loading the ad pod manifest.

## Prerequisites

Before continuing, ensure you have the following:

- The DAI Pod serving enabled on your Google Ad Manager network.
- A livestream event with type **Pod serving manifest** . To create the event, see [Set up a livestream for DAI](https://support.google.com/admanager/answer/7294289).

### Follow recommendations

Before you
[generate the ad pod manifest URL](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/live/get-started/sgai#generate-ad-pod-manifest-url), we recommend
you call the
[Early Ad Break Notification (EABN) API](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/eabn)
to specify the expected duration, targeting information, and other
parameters of each ad break.

For production and test streams, call the EABN API, especially if your ad
network has any programmatic campaigns. For more information, see
[Features and guidelines for Programmatic Direct](https://support.google.com/admanager/answer/9345607).

## Make a stream registration request

When a user starts a content stream in your video player app, you make a stream
registration request with targeting parameters to create a streaming session
on Ad Manager. For details on making a stream registration request, see
[Method:stream](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_stream).
Afterwards, you receive
[response data](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#stream)
from the request.

The following examples make a stream registration request:

### Plain text HTTP

- Request:

    authority: dai.google.com
    method: POST
    path: /ssai/pods/api/v1/network/51636543/custom_asset/hls-podserving-manifest/stream
    scheme: https
    content-type: application/x-www-form-urlencoded

    cust_params=customID%253D1543216789%2526anotherKey%253Dvalue1%252Cvalue2

- Response:

    {
        "manifest_format": "hls",
        "media_verification_url": "https://dai.google.com/view/p/service/linear/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/loc/TUL/network/51636543/event/TFyZF0IoSpqvCLtLv8JdCw/media/",
        "metadata_url": "https://dai.google.com/linear/pods/hls/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/metadata",
        "polling_frequency": 10,
        "session_update_url": "https://dai.google.com/linear/v1/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/session",
        "stream_id": "24fd4e7c-95a0-42be-8874-00625139b9db:TUL"
    }

### Shell

- Command line:

    curl \
    -H "Host: dai.google.com" \
    -H "content-type: application/x-www-form-urlencoded" \
      --data-binary "cust_params=channelID%253D1543216789%2526anotherKey%253Dvalue1%252Cvalue2" \
      --compressed "https://dai.google.com/ssai/pods/api/v1/network/51636543/custom_asset/hls-podserving-manifest/stream"

- Output:

    {
        "manifest_format": "hls",
        "media_verification_url": "https://dai.google.com/view/p/service/linear/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/loc/TUL/network/51636543/event/TFyZF0IoSpqvCLtLv8JdCw/media/",
        "metadata_url": "https://dai.google.com/linear/pods/hls/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/metadata",
        "pod_manifest_url": "https://dai.google.com/linear/pods/v1/hls/event/TFyZF0IoSpqvCLtLv8JdCw/pod/$pod-id$.m3u8?stream_id=24fd4e7c-95a0-42be-8874-00625139b9db%3ATUL",
        "polling_frequency": 10,
        "session_update_url": "https://dai.google.com/linear/v1/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/session",
        "stream_id": "24fd4e7c-95a0-42be-8874-00625139b9db:TUL"
    }

### Javascript

- Using Fetch API:

    const response = await fetch("https://dai.google.com/ssai/pods/api/v1/network/51636543/custom_asset/hls-podserving-manifest/stream", {
      "headers": {
        "content-type": "application/x-www-form-urlencoded",
      },
      "body": "cust_params=channelID%3D1543216789%26anotherKey%3Dvalue1%2Cvalue2",
      "method": "POST",
    });

      const stream = await response.json();
      console.log(stream);

- Console log:

    {
        "stream_id": "24fd4e7c-95a0-42be-8874-00625139b9db:TUL",
        "media_verification_url": "https://dai.google.com/view/p/service/linear/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/loc/TUL/network/51636543/event/TFyZF0IoSpqvCLtLv8JdCw/media/",
        "metadata_url": "https://dai.google.com/linear/pods/hls/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/metadata",
        "session_update_url": "https://dai.google.com/linear/v1/pa/event/TFyZF0IoSpqvCLtLv8JdCw/stream/24fd4e7c-95a0-42be-8874-00625139b9db:TUL/session",
        "polling_frequency": 10,
        "pod_manifest_url": "https://dai.google.com/linear/pods/v1/hls/event/TFyZF0IoSpqvCLtLv8JdCw/pod/$pod-id$.m3u8?stream_id=24fd4e7c-95a0-42be-8874-00625139b9db%3ATUL",
        "manifest_format": "hls"
    }

## Poll for ad break metadata

After you make a stream registration request, poll for the ad metadata. To
poll, you set a timer using the `polling_frequence` in the stream response at
the registration step to call the ad
[metadata](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_metadata).
For each poll, you might receive a partial list of ads with metadata as they
become available.

## Generate the ad pod manifest URL

Construct a URL for the
[pod resource](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_pod_manifest)
of the Pod Serving API. Afterwards, pass the URL to a video player to start
loading the ad pod.

The following example demonstrates the structure of the ad pod manifest URL:

    https://dai.google.com/linear/pods/v1/hls/network/51636543/custom_asset/pod_serving_hls_manifest_mp4/ad_break_id/ab101.m3u8?stream_id=24fd4e7c-95a0-42be-8874-00625139b9db:TUL&pd=120000

> [!NOTE]
> **Note:** The ad break parameters, such as `ad_break_id`, `duration`, `cust_params` and `scte35` must be the same for all clients watching the same livestream, while the stream ID is unique for each client. If you choose to generate the ad pod manifest URL on the server side and insert the generated URLs in the stream manifest, follow your manifest manipulator server documentation on sending the stream ID from the clients and generate the other ad break parameters.

You can calculate the ad pod manifest URL parameters based on the ad break
information retrieved from the video player or a server notification. For
requirements of these parameters, see
[Method: pod manifest](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_hls_pod_manifest).

## Play the ad pod manifest

On the client video player app, begin content stream playback with a primary
video player and follow your video player's documentation on observing the
playback and ad schedule, if relevant.

If you generate the ad pod manifest URLs and insert those in the manifest on the
server side, observe the video player's upcoming ad break events, and ensure to
subscribe to id3 events during each ad break playback. If you schedule the ad
break events from the client side, subscribe to the id3 events on creation.

## Report impressions and ad events

When a video player plays the ad pod and encounters id3 timed metadata,
[listen to ad events](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/live/client#listen_for_ad_events)
that the video player triggers and process them to
[send media verification pings](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/live/client#send_media_verification_pings).

> [!IMPORTANT]
> **Important:** Don't delay the ping to the media verification URL. We recommend you ping immediately and not longer than one minute.