A stream request registers a session for a livestream event.
For details, see [Make a stream request](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/full-service/reference/live#method_stream)

This page covers using HMAC token to authenticate the stream requests.

## Before you begin

Before you continue, do the following:

- Complete the [prerequisites](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/full-service/stream-session-overview#prerequisites).
- In your [Google Ad Manager account](https://admanager.google.com), enable **Stream create authentication keys** for your livestream event. If you use token authentication, the key is required.

## Generate an HMAC token

To generate a token, do the following:

1. Gather your livestream's asset key and expiration time. For more information, see [Enable authentication for requests to create DAI stream sessions](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/full-service/stream-session-overview#enable_authentication_for_requests_to_create_dai_stream_sessions)
2. Sort the following parameters alphabetically and separate the parameters with the tilde
   `~` character:

       event=ASSET_KEY~exp=EXPIRATION

   Replace the following:
   - `ASSET_KEY`: **Required.** The livestream event's asset key.
   - `EXPIRATION`: **Required.** The expiration timestamp for the token in Unix epoch time.
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:

       event=...~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 signs and encodes a token string that expires within 60
seconds:

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

    echo "Current: $EPOCHSECONDS"
    echo "Future: $future_epoch"
    # Current: 1767389133
    # Future: 1767389193

    # Sample DAI stream authentication key
    key="DE0E9..."

    # Sort parameters in the token string
    token="event=YRB0Bl0oQRCb5J-maPpJUQ~exp=1767389193"

    # Generate the token's signature.
    echo -n $token | openssl dgst -sha256 -mac HMAC -macopt key:$key
    # SHA2-256(stdin)= 9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

    # Sign the token: event=YRB0Bl0oQRCb5J-maPpJUQ~exp=1767389193~hmac=9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

    # Encode the token: event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248

## Use the HMAC token to request a livestream session

To authenticate your stream create request with an HMAC token, do one of the
following:

### `Authorization` request header

      curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream" \
      -X POST \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -H "Authorization: DCLKDAI token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248"

### Query string parameter

      curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream?auth-token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248" \
      -X POST \
      -H "Content-Type: application/x-www-form-urlencoded"

### Form data field

      curl "https://dai.google.com/linear/v1/hls/event/YRB0Bl0oQRCb5J-maPpJUQ/stream" \
      -X POST \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "auth-token=event%3DYRB0Bl0oQRCb5J%2DmaPpJUQ%7Eexp%3D1767389193%7Ehmac%3D9935a013957e5ce893a7ee444d3d452fd0de7d273ff8b65471ddd4619b80d248"

If successful, you see the following JSON response:

      {
      "hls_master_playlist": "https://dai.google.com/linear/hls/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/master.m3u8",
      "media_verification_url": "https://dai.google.com/view/p/service/linear/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/loc/DLS/network/21775744923/event/YRB0Bl0oQRCb5J-maPpJUQ/media/",
      "metadata_url": "https://dai.google.com/linear/v1/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/metadata",
      "polling_frequency": 10,
      "session_update_url": "https://dai.google.com/linear/v1/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/session",
      "stream_id": "e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS",
      "stream_manifest": "https://dai.google.com/linear/hls/pa/event/YRB0Bl0oQRCb5J-maPpJUQ/stream/e91f907e-6a0a-4795-8c96-c8e36e89cbf6:DLS/master.m3u8"
      }

To understand the response structure and status codes, see [Method: stream](https://developers.google.com/ad-manager/dynamic-ad-insertion/api/full-service/reference/live#method_stream).
If authentication fails, you see the following error:

      <!DOCTYPE html>
      <html lang=en>
        <meta charset=utf-8>
        <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
        <title>Error 401 (Unauthorized)!!1</title>
        ...
        <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
        <p><b>401.</b> <ins>That's an error.</ins>
        <p><ins>That's all we know.</ins>