Add creatives to finalized deals

If your technical account manager enabled you to manually start serving deals, we recommend you use the buyers.finalizedDeals.addCreative method to add the creatives you want to place with the programmatic guaranteed deal.

When you specify a creative to add to the finalized deal, you must use the creative name from the Real-time Bidding API’s buyers.creatives resource.

You should add creatives before calling buyers.finalizedDeals.setReadyToServe.

You can only use addCreative for programmatic guaranteed deals. addCreative returns an error for other deal types.

REST

Request

POST https://authorizedbuyersmarketplace.googleapis.com/v1/buyers/12345678/finalizedDeals/1840860:addCreative?alt=json
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

Response

{
 "name": "buyers/12345678/finalizedDeals/1840860",
 "deal": {
   "name": "buyers/12345678/proposals/MP8642048/deals/1840860",
   "createTime": "2031-03-26T05:53:33.053Z",
   "updateTime": "2031-03-27T05:54:33.442Z",
   "displayName": "test-pg-deal-4",
   "buyer": "buyers/12345678",
   "publisherProfile": "buyers/12345678/publisherProfiles/PP12345",
   "flightStartTime": "2032-03-31T16:00:00Z",
   "flightEndTime": "2032-03-31T18:59:00Z",
   "targeting": {
     "inventorySizeTargeting": {
       "targetedInventorySizes": [
         {
           "width": "200",
           "height": "200",
           "type": "PIXEL"
         },
         {
           "width": "234",
           "height": "60",
           "type": "PIXEL"
         },
         {
           "width": "240",
           "height": "400",
           "type": "PIXEL"
         },
         {
           "width": "300",
           "height": "250",
           "type": "PIXEL"
         },
         {
           "width": "300",
           "height": "600",
           "type": "PIXEL"
         },
         {
           "width": "300",
           "height": "1050",
           "type": "PIXEL"
         }
       ]
     }
   },
   "creativeRequirements": {
     "creativePreApprovalPolicy": "SELLER_PRE_APPROVAL_NOT_REQUIRED",
     "creativeSafeFrameCompatibility": "COMPATIBLE",
     "programmaticCreativeSource": "ADVERTISER",
     "creativeFormat": "DISPLAY"
   },
   "deliveryControl": {
     "deliveryRateType": "EVENLY"
   },
   "billedBuyer": "buyers/12345678",
   "dealType": "PROGRAMMATIC_GUARANTEED",
   "programmaticGuaranteedTerms": {
     "guaranteedLooks": "1",
     "fixedPrice": {
       "type": "CPM",
       "amount": {
         "currencyCode": "USD",
         "nanos": 10000000
       }
     },
     "reservationType": "STANDARD"
   },
   "sellerTimeZone": {
     "id": "Asia/Shanghai"
   }
 },
 "dealServingStatus": "ENDED",
 "dealPausingInfo": {
   "pausingConsented": true
 },
 "rtbMetrics": {},
 "readyToServe": false
}

C#

/* Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using Google.Apis.AuthorizedBuyersMarketplace.v1;
using Google.Apis.AuthorizedBuyersMarketplace.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;

namespace Google.Apis.AuthorizedBuyersMarketplace.Examples.v1.Buyers.FinalizedDeals
{
    /// <summary>
    /// Adds a creative to a given finalized deal that will be used in bids.
    ///
    /// It is recommended that those configuring programmatic guaranteed deals use this method to
    /// associate at least one creative that is ready to be placed in bids with the deal before
    /// signaling that the deal is ready to begin serving with finalizedDeals.setReadyToServe.
    ///
    /// A buyer's creatives can be viewed with the Real-time Bidding API:
    /// https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.creatives
    /// </summary>
    public class AddCreativeToFinalizedDeals : ExampleBase
    {
        private AuthorizedBuyersMarketplaceService mkService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public AddCreativeToFinalizedDeals()
        {
            mkService = Utilities.GetAuthorizedBuyersMarketplaceService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "This code example adds a creative to a given finalized deal.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {
                "account_id", "creative_id", "deal_id"};
            bool showHelp = false;

            string accountId = null;
            string creativeId = null;
            string dealId = null;

            OptionSet options = new OptionSet {
                "Adds a creative to the specified finalized deal for the given buyer account.",
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "a|account_id=",
                    ("[Required] The resource ID of the buyers resource under which the " +
                     "finalized deal is being accessed. This will be used to construct the " +
                     "finalized deal name used as a path parameter for the " +
                     "finalizedDeals.addCreative request, as well as the creative name included " +
                     "in the request body."),
                    a => accountId = a
                },
                {
                    "c|creative_id=",
                    ("[Required] The resource ID of the buyers.creatives resource that the " +
                     "buyer is adding to a finalized deal. This will be used to construct the " +
                     "creative name included in the body of the finalizedDeals.addCreative " +
                     "request."),
                    c => creativeId = c
                },
                {
                    "d|deal_id=",
                    ("[Required] The resource ID of the finalized deal that the creative is " +
                     "being added to. This will be used to construct the finalized deal name " +
                     "used as a path parameter for the finalizedDeals.addCreative request. "),
                    d => dealId = d
                },
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if (showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set optional arguments.
            parsedArgs["account_id"] = accountId;
            parsedArgs["creative_id"] = creativeId;
            parsedArgs["deal_id"] = dealId;
            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            string accountId = (string) parsedArgs["account_id"];
            string creativeId = (string) parsedArgs["creative_id"];
            string dealId = (string) parsedArgs["deal_id"];
            string finalizedDealName = $"buyers/{accountId}/finalizedDeals/{dealId}";
            string creativeName = $"buyers/{accountId}/creatives/{creativeId}";

            AddCreativeRequest addCreativeRequest = new AddCreativeRequest()
            {
                Creative = creativeName
            };

            Console.WriteLine("Adding creative with name \"{0}\" to finalized deal with name " +
                "\"{1}\":", creativeName, finalizedDealName);

            BuyersResource.FinalizedDealsResource.AddCreativeRequest request =
                mkService.Buyers.FinalizedDeals.AddCreative(
                    addCreativeRequest, finalizedDealName);
            FinalizedDeal response = null;

            try
            {
                response = request.Execute();
            }
            catch (Exception exception)
            {
                throw new ApplicationException(
                    $"Marketplace API returned error response:\n{exception.Message}");
            }

            Utilities.PrintFinalizedDeal(response);
        }
    }
}

Java

/*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.api.services.samples.authorizedbuyers.marketplace.v1.buyers.finalizedDeals;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.AddCreativeRequest;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.FinalizedDeal;
import com.google.api.services.samples.authorizedbuyers.marketplace.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * This sample illustrates how to add a creative to a given finalized deal that will be used in
 * bids.
 *
 * <p>It is recommended that those configuring programmatic guaranteed deals use this method to
 * associate at least one creative that is ready to be placed in bids with the deal before signaling
 * that the deal is ready to begin serving with finalizedDeals.setReadyToServe.
 *
 * <p>A buyer's creatives can be viewed with the Real-time Bidding API:
 * https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.creatives
 */
public class AddCreativeToFinalizedDeals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    String creativeId = parsedArgs.getString("creative_id");
    Long dealId = parsedArgs.getLong("deal_id");
    String name = String.format("buyers/%d/finalizedDeals/%d", accountId, dealId);
    String creativeName = String.format("buyers/%d/creatives/%s", accountId, creativeId);

    AddCreativeRequest addCreativeRequest = new AddCreativeRequest();
    addCreativeRequest.setCreative(creativeName);

    FinalizedDeal finalizedDeal = null;

    try {
      finalizedDeal =
          marketplaceClient
              .buyers()
              .finalizedDeals()
              .addCreative(name, addCreativeRequest)
              .execute();
    } catch (IOException ex) {
      System.out.printf("Marketplace API returned error response:%n%s", ex);
      System.exit(1);
    }

    System.out.printf(
        "Adding creative with name \"%s\" to finalized deal with name \"%s\":%n",
        creativeName, name);
    Utils.printFinalizedDeal(finalizedDeal);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("AddCreativeToFinalizedDeals")
            .build()
            .defaultHelp(true)
            .description(("Adds a creative to a given finalized deal that will be used in bids."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource under which the finalized was created. This"
                + " will be used to construct the parent used as a path parameter for the"
                + " finalizedDeals.addCreative request, as well as the creative name included in"
                + " the request body.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-c", "--creative_id")
        .help(
            "The resource ID of the buyers.creatives resource that the buyer is adding to a"
                + " finalized deal. This will be used to construct the creative name included in"
                + " the request body.")
        .required(true);
    parser
        .addArgument("-d", "--deal_id")
        .help(
            "The resource ID of the buyers.finalizedDeals resource that the creative is being "
                + "added to. This will be used to construct the name used as a path parameter "
                + "for the finalizedDeals.addCreative request.")
        .required(true)
        .type(Long.class);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    AuthorizedBuyersMarketplace client = null;
    try {
      client = Utils.getMarketplaceClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Marketplace API service:%n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:%n%s", ex);
      System.exit(1);
    }

    execute(client, parsedArgs);
  }
}

Python

#!/usr/bin/python
#
# Copyright 2021 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Adds a creative to a given finalized deal that will be used in bids.

It is recommended that those configuring programmatic guaranteed deals use this
method to associate at least one creative that is ready to be placed in bids
with the deal before signaling that the deal is ready to begin serving with
finalizedDeals.setReadyToServe.

A buyer's creatives can be viewed with the Real-time Bidding API:
https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.creatives
"""


import argparse
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../..'))

from googleapiclient.errors import HttpError

import util


_FINALIZED_DEALS_NAME_TEMPLATE = 'buyers/%s/finalizedDeals/%s'
_CREATIVE_NAME_TEMPLATE = 'buyers/%s/creatives/%s'

DEFAULT_BUYER_RESOURCE_ID = 'ENTER_BUYER_RESOURCE_ID_HERE'
DEFAULT_FINALIZED_DEAL_RESOURCE_ID = 'ENTER_DEAL_RESOURCE_ID_HERE'


def main(marketplace, args):
    account_id = args.account_id
    finalized_deal_name = _FINALIZED_DEALS_NAME_TEMPLATE % (
        account_id, args.deal_id)

    body = {
        "creative": _CREATIVE_NAME_TEMPLATE % (account_id, args.creative_id)
    }

    print(
        f'Adding creative to finalized deal with name "{finalized_deal_name}":')
    try:
        # Construct and execute the request.
        response = marketplace.buyers().finalizedDeals().addCreative(
            deal=finalized_deal_name, body=body).execute()
    except HttpError as e:
        print(e)
        sys.exit(1)

    pprint.pprint(response)


if __name__ == '__main__':
    try:
        service = util.get_service(version='v1')
    except IOError as ex:
        print(f'Unable to create marketplace service - {ex}')
        print('Did you specify the key file in util.py?')
        sys.exit(1)

    parser = argparse.ArgumentParser(
        description=('Add a creative to a finalized deal for the given buyer '
                     'account, deal, and creative ID.'))
    # Required fields.
    parser.add_argument(
        '-a', '--account_id', default=DEFAULT_BUYER_RESOURCE_ID,
        help=('The resource ID of the buyers resource for which the finalized '
              'deal is being accessed. This will be used to construct the '
              'name used as a path parameter for the '
              'finalizedDeals.addCreative request.'))
    parser.add_argument(
        '-c', '--creative_id', required=True,
        help=('The resource ID of the creatives resource that is to be added '
              'to the finalized deal. This will be used to construct the name '
              'of the creative, which will be included in the body of the '
              'finalizedDeals.addCreative request.'))
    parser.add_argument(
        '-d', '--deal_id', default=DEFAULT_FINALIZED_DEAL_RESOURCE_ID,
        help=('The resource ID of the buyers.finalizedDeals resource that is '
              'being accessed. Note that this will be identical to the '
              'resource ID of the corresponding buyers.proposals.deals '
              'resource. This will be used to construct the name used as a '
              'path parameter for the finalizedDeals.addCreative request.'))

    main(service, parser.parse_args())