Unlike those that are served by other types of line items, creatives served by
Demand Gen ads are constructed in the [`AdGroupAd`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adGroupAds#AdGroupAd) resources
themselves. The image and video assets assigned to ads to build these creatives
are represented in the Display \& Video 360 API by [`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resources.

Before creating an [`AdGroupAd`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adGroupAds#AdGroupAd) resource, create the relevant
[`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resources that the ad will use if they don't already
exist. If they were previously created using the UI or API, you can retrieve
existing assets using the `advertisers.adAssets` service [`get`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets/get)
and [`list`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets/list) methods.

> [!CAUTION]
> **Caution:** [`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resources must be used in Demand Gen ads. Attempting to use [`Asset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.assets) resources, which are used in typical [`Creative`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.creatives#Creative) resources, when creating an [`AdGroupAd`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adGroupAds#AdGroupAd) resource will return an error.

Image and video [`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resources are created using different
methods:

- Image assets must be uploaded to Display \& Video 360 using the [`advertisers.adAssets.upload`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets/upload) method.
- Video assets must be associated using a YouTube video ID and created using the [`advertisers.adAssets.create`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets/create) method.

The [`adAssetId`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset.FIELDS.ad_asset_id) of an [`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resource is used
to associate an asset with a Demand Gen ad.

> [!NOTE]
> **Note:** See our [Labeling AI content in ads](https://developers.google.com/display-video/api/guides/concepts/campaign-resources/ai-content-labels) guide for information on how to label assets as created or edited using AI.

## Upload image assets

Upload image files to create `AD_ASSET_TYPE_IMAGE` assets that can be used as
companion banners, logos, and marketing images.

> [!CAUTION]
> **Caution:** Resolution and size of images are important. If the image asset in an ad does not meet the ad requirements, the [`advertisers.adGroupAds.create`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adGroupAds/create) request will fail.

Here's how to upload an image asset to create an [`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset)
resource:

### Java

```java
// Provide the parent advertiser ID to upload the media file under.
long advertiserId = advertiser-id;

// Provide the local path to the media file.
String assetPath = asset-path;

// Get filename from path.
String assetFilename = new File(assetPath).getName();

// Create the asset upload request content.
UploadAdAssetRequest content =
    new UploadAdAssetRequest()
        .setFilename(assetFilename)
        .setAdAssetType("AD_ASSET_TYPE_IMAGE");

// Parse filename for appropriate MIME type.
FileNameMap filenameMap = URLConnection.getFileNameMap();
String mimeType = filenameMap.getContentTypeFor(assetFilename);
if (mimeType == null) {
  mimeType = "application/octet-stream";
}

// Create input stream for the ad asset.
InputStreamContent assetStream =
    new InputStreamContent(mimeType, new FileInputStream(assetPath));

// Configure the ad asset upload request.
AdAssets.Upload uploadRequest =
    service
        .advertisers()
        .adAssets()
        .upload(advertiserId, content, assetStream);

// Upload the asset.
UploadAdAssetResponse assetResponse = uploadRequest.execute();

// Display the new asset media ID.
System.out.printf(
    "Ad asset was created with asset ID %s.",
    assetResponse.getAdAsset().getAdAssetId());
```

### Python

```python
# Import the object used as the media body for the upload request.
from apiclient.http import MediaFileUpload

# Provide the parent advertiser ID to upload the media file under.
advertiser_id = advertiser-id

# Provide the filename and local path to the media file.
asset_filename = asset-filename
asset_path = asset-path

# Create the request body.
body = {"filename": asset_filename, "adAssetType": "AD_ASSET_TYPE_IMAGE"}

# Create the upload object and use a default MIME type if not identified.
media = MediaFileUpload(asset_path)
if not media.mimetype():
  media = MediaFileUpload(asset_path, "application/octet-stream")

# Upload the asset.
upload_response = (
    service.advertisers()
    .adAssets()
    .upload(advertiserId=advertiser_id, body=body, media_body=media)
    .execute()
)

# Display the new ad asset.
print(f"Ad asset {upload_response['adAsset']['name']} was created.")
```

### PHP

```php
// Provide the parent advertiser ID to upload the media file under.
$advertiserId = advertiser-id;

// Provide the local path to the media file.
$assetPath = asset-path;

// Provide the name of the media file.
$assetFilename = asset-filename;

// Create the request object.
$body = new Google_Service_DisplayVideo_UploadAdAssetRequest();
$body->setFilename($assetFilename);
$body->setAdAssetType('AD_ASSET_TYPE_IMAGE');

// Set the query parameters
$optParams = array(
    'data' => file_get_contents($assetPath),
    'mimeType' => mime_content_type($assetFilename),
    'uploadType' => 'media'
);

// Upload the asset.
try {
    $result = $this->service->advertisers_adAssets->upload(
        $advertiserId,
        $body,
        $optParams
    );
} catch (\Exception $e) {
    $this->renderError($e);
    return;
}

// Display the new ad asset.
printf(
    '<p>Ad Asset was created with asset ID %s.</p>',
    $result->getAdAsset()->getAdAssetId()
);
```

## Create YouTube assets

Provide YouTube video IDs to create `AD_ASSET_TYPE_YOUTUBE_VIDEO` assets that
can be used in Demand Gen video ads.

Here's how to create a YouTube video asset to create an
[`AdAsset`](https://developers.google.com/display-video/api/reference/rest/v4/advertisers.adAssets#AdAsset) resource:

### Java

```java
// Provide the ID of the parent advertiser.
long advertiserId = advertiser-id;

// Provide the YouTube video ID.
String youtubeVideoId = youtube-video-id;

// Create the ad asset structure.
AdAsset adAsset =
    new AdAsset()
        .setAdAssetType("AD_ASSET_TYPE_YOUTUBE_VIDEO")
        .setYoutubeVideoAsset(
            new YoutubeVideoAsset().setYoutubeVideoId(youtubeVideoId));

// Configure the create request.
AdAssets.Create request =
    service
        .advertisers()
        .adAssets()
        .create(
            advertiserId, new CreateAdAssetRequest().setAdAsset(adAsset));

// Create the ad asset.
AdAsset response = request.execute();

// Display the new ad asset.
System.out.printf("Ad asset %s was created.", response.getName());
```

### Python

```python
# Provide the ID of the parent advertiser.
advertiser_id = advertiser-id

# Provide the YouTube video ID.
youtube_video_id = youtube-video-id

# Create the ad asset structure.
ad_asset_create_body = {
    "adAsset": {
        "adAssetType": "AD_ASSET_TYPE_YOUTUBE_VIDEO",
        "youtubeVideoAsset": {"youtubeVideoId": youtube_video_id},
    }
}

# Create the ad asset.
response = (
    service.advertisers()
    .adAssets()
    .create(advertiserId=advertiser_id, body=ad_asset_create_body)
    .execute()
)

# Display the new ad asset.
print(f"Ad asset {response['name']} was created.")
```

### PHP

```php
// Provide the ID of the parent advertiser.
$advertiserId = advertiser-id;

// Provide the YouTube video ID.
$youtubeVideoId = youtube-video-id;

// Create the ad asset structure.
$youtubeVideoAsset =
    new Google_Service_DisplayVideo_YoutubeVideoAsset();
$youtubeVideoAsset->setYoutubeVideoId($youtubeVideoId);
$adAsset = new Google_Service_DisplayVideo_AdAsset();
$adAsset->setAdAssetType('AD_ASSET_TYPE_YOUTUBE_VIDEO');
$adAsset->setYoutubeVideoAsset($youtubeVideoAsset);

// Create the create request.
$createAdAssetRequest =
    new Google_Service_DisplayVideo_CreateAdAssetRequest();
$createAdAssetRequest->setAdAsset($adAsset);

// Create the ad asset.
try {
    $result =
        $this->service->advertisers_adAssets->create(
            $advertiserId,
            $createAdAssetRequest
        );
} catch (\Exception $e) {
    $this->renderError($e);
    return;
}

// Display the new ad asset.
printf(
    '<p>Ad Asset was created with asset ID %s.</p>',
    $result['adAssetId']
);
```