For server-side ad stitching, your manifest manipulator makes ad pod segment
requests to Google DAI. For more information, see [Build ad segment URLs](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/live/manipulator-basic?protocol=hls#build_ad_segment_urls).

This page covers authenticating ad pod segment requests using the HMAC token.

## Before you begin

Before you continue, do the following:

- Complete the [prerequisites](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/live/pod-request-overview#prerequisites).
- Ensure the **Pod resource authentication keys** are enabled in your livestream event in your [Google Ad Manager](https://admanager.google.com) account.

## Generate an HMAC token

To generate a token, do the following:

1. Collect the path and query parameters (except auth-token) populated for your pod segment request. For a full list, see [Method: pod segment](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_pod_segment).
2. Organize your parameters into a single string. You must sort the parameters alphabetically
   and separate them with the tilde `~` character, for example:

       custom_asset_key=CUSTOM_ASSET_KEY~exp=EXPIRATION~network_code=NETWORK_CODE~pd=POD_DURATION~pod_id=POD_IDENTIFIER

3. Calculate a SHA-256 hash of the token string using your DAI authentication key.

4. Format the hash output in hexadecimal.

5. To sign the token string, append the signature at the end of the parameters gathered earlier:

       custom_asset_key=...~hmac=HMAC_SIGNATURE

   Replace `HMAC_SIGNATURE` with the signature you generated by
   hashing the token string using your DAI authentication key.
6. To pass the signed token string safely, apply URL-encoding to the signed token string.

   The following example generates the URL-encoded value of a signed token string:

### HLS

    # Add 60 seconds to the current time
    future_epoch=$((EPOCHSECONDS + 60))

    echo "Current: $EPOCHSECONDS"
    echo "Future: $future_epoch"
    # Current: 1774465950
    # Future: 1774466010

    # Sample DAI pod resource authentication key
    key="EB08..."

    # Sort parameters in the token string
    token="ad_break_id=ab1~custom_asset_key=hls-pod-serving-redirect-auth-stream-pod~exp=1774466010~network_code=21775744923~pd=30000"

    # Generate the token's signature.
    echo -n $token | openssl dgst -sha256 -mac HMAC -macopt key:$key

    # SHA2-256(stdin)= ff38abab31b436351e20ecd57bcc5b97acd9461abb71c4cf9c9731add965ecf2

    # Sign the token: ad_break_id=ab1~custom_asset_key=hls-pod-serving-redirect-auth-stream-pod~exp=1774466010~network_code=21775744923~pd=30000~hmac=ff38abab31b436351e20ecd57bcc5b97acd9461abb71c4cf9c9731add965ecf2

    # Encode the token: ad_break_id%3Dab1~custom_asset_key%3Dhls-pod-serving-redirect-auth-stream-pod~exp%3D1774466010~network_code%3D21775744923~pd%3D30000~hmac%3Dff38abab31b436351e20ecd57bcc5b97acd9461abb71c4cf9c9731add965ecf2

### DASH

    # Add 60 seconds to the current time
    future_epoch=$((EPOCHSECONDS + 60))

    echo "Current: $EPOCHSECONDS"
    echo "Future: $future_epoch"
    # Current: 1769540517
    # Future: 1769540577

    # Sample DAI pod resource authentication key
    key="EB08..."

    # Sort parameters in the token string
    token="ad_break_id=ab1~custom_asset_key=dash-pod-serving-redirect-auth-stream-pod~exp=1774466641~network_code=21775744923~pd=30000"

    # Generate the token's signature.
    echo -n $token | openssl dgst -sha256 -mac HMAC -macopt key:$key

    # SHA2-256(stdin)= 7249f9193778f2318314519ff2cea5c47958bc7fdd2eaf24008352867af0a050

    # Sign the token: ad_break_id=ab1~custom_asset_key=dash-pod-serving-redirect-auth-stream-pod~exp=1774466641~network_code=21775744923~pd=30000~hmac=7249f9193778f2318314519ff2cea5c47958bc7fdd2eaf24008352867af0a050

    # Encode the token: ad_break_id%3Dab1~custom_asset_key%3Ddash-pod-serving-redirect-auth-stream-pod~exp%3D1774466641~network_code%3D21775744923~pd%3D30000~hmac%3D7249f9193778f2318314519ff2cea5c47958bc7fdd2eaf24008352867af0a050

## Authenticate an HLS ad pod segment request

To authenticate your pod resource requests, use the `auth-token` query string
parameter to pass the URL-encoded signed HMAC token.

### HLS

The following example uses an HMAC token to authenticate an HLS pod segment
request:

    curl --include "https://dai.google.com/linear/pods/v1/seg/network/21775744923/custom_asset/hls-pod-serving-redirect-auth-stream-pod/ad_break_id/ab1/profile/media-ts-4628000bps/0.ts?stream_id=51b85d28-7ed5-48da-bfd8-e013b7d7b204:DLS&&sd=10000&pd=30000&auth-token=ad_break_id%3Dab1~custom_asset_key%3Dhls-pod-serving-redirect-auth-stream-pod~exp%3D1774466010~network_code%3D21775744923~pd%3D30000~hmac%3Dff38abab31b436351e20ecd57bcc5b97acd9461abb71c4cf9c9731add965ecf2"

If successful, you see the following response:

    ...
    < HTTP/2 302
    < access-control-allow-headers: Authorization
    < access-control-allow-origin: *
    < access-control-expose-headers: Location
    < cache-control: no-cache, no-store, max-age=0, must-revalidate
    < date: Wed, 25 Mar 2026 18:13:40 GMT
    < expires: Mon, 01 Jan 1990 00:00:00 GMT
    < location: https://redirector.googlevideo.com/....
    < pragma: no-cache
    < x-content-type-options: nosniff
    < x-frame-options: SAMEORIGIN
    ...

To understand the response structure and status codes, refer to [Method: pod segment](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_pod_segment).

If authentication fails, you see the `x-ad-manager-dai-warning`:

    ...
    < HTTP/2 302
    < access-control-allow-headers: Authorization
    < access-control-allow-origin: *
    < access-control-expose-headers: Location
    < cache-control: no-cache, no-store, max-age=0, must-revalidate
    < date: Wed, 25 Mar 2026 18:17:21 GMT
    < expires: Mon, 01 Jan 1990 00:00:00 GMT
    < location: https://redirector.googlevideo.com/....
    < pragma: no-cache
    < x-ad-manager-dai-warning: Unable to create ad break due to Unauthorized error (skipping ad break creation)
    < x-content-type-options: nosniff
    ...

### DASH

The following example uses an HMAC token to authenticate a DASH pod segment
request:

    curl --include "https://dai.google.com/linear/pods/v1/seg/network/21775744923/custom_asset/dash-pod-serving-redirect-auth-stream-pod/ad_break_id/ab1/profile/media-ts-4628000bps/0.ts?stream_id=8b061ab5-1efc-4e4d-882f-ae3c071df854:ATL&&sd=10000&pd=30000&auth-token=ad_break_id%3Dab1~custom_asset_key%3Ddash-pod-serving-redirect-auth-stream-pod~exp%3D1774466641~network_code%3D21775744923~pd%3D30000~hmac%3D7249f9193778f2318314519ff2cea5c47958bc7fdd2eaf24008352867af0a050"

If successful, you see the following response:

    ...
    HTTP/2 302
    ..
    location: https://redirector.googlevideo.com/....
    ...

To understand the response structure and status codes, refer to [Method: pod segment](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_pod_segment).

If authentication fails, you see the **x-ad-manager-dai-warning** as follows:

    ...
    HTTP/2 302
    ..
    location: https://redirector.googlevideo.com/....
    pragma: no-cache
    x-ad-manager-dai-warning: Unable to create ad break due to Unauthorized error (skipping ad break creation)
    x-content-type-options: nosniff
    ...