Google Ads API is returning to beta status. Please read our blog post for more details.

Account Budget

Account budgets control what an account can spend over a specific period of time by defining budget properties like spend limit, start time, and end time. They must point to one of the account's billing setups, to indicate which specific Payments account will be billed. You can create, update, and remove the AccountBudget by sending AccountBudgetProposal objects.

AccountBudgetProposal objects are reviewed by Google prior to being applied. Reviews are typically completed in less than one hour, however you should ensure that budgets are approved well in advance of their requested start time.

Creating an account budget proposal

Creating a new account budget allows you to control a customer's spending behaviour. Use the AccountBudgetProposalService to create a new AccountBudgetProposal. You should set AccountBudgetProposalType to CREATE to specify that a new budget should be created. Refer to the management section of this guide for other operations.

Remember to use a billing setup with a payments account where you have write access. Refer to the billing setup guide for details.

AccountBudgetProposal proposal = AccountBudgetProposal.newBuilder()
  .setBillingSetup(StringValue.of("customer/1234567890/billingSetups/1"))
  .setProposalType(AccountBudgetProposalType.CREATE)
  .setProposedName(StringValue.of("Example account budget"))
  .setProposedStartDateTime(StringValue.of("2020-01-02 03:03:03"))
  .setProposedEndDateTime(StringValue.of("2021-02-03 04:04:04"))
  .setProposedSpendingLimitMicros(Int64Value.of(10_000))
  .build();

// Send request to Google Ads API (not shown).

In account budget proposal requests, proposed_start_date_time and proposed_end_date_time are always in the customer's account timezone; you cannot specify a timezone. The proposed_spending_limit is always measured in the account's currency; specify this using "micro" units, so $1.00 = 1,000,000.

Optionally, you can include a Purchase Order number which will show next to these charges on the invoice. This does not have any effect on budget delivery.

Retrieving existing account budgets

AccountBudget objects represent the end result of applying proposals. After a proposal is approved, its changes (subject to any adjustments) will result in the creation of a new account budget or an update to an existing one. This depends on the AccountBudgetProposalType in the request. An approved CREATE request will create a new account budget. An UPDATE, END, or REMOVE request will take the appropriate action on an existing account budget.

The query below will fetch all the account budgets in an account.

Java

// Copyright 2018 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.ads.googleads.examples.billing;

import com.beust.jcommander.Parameter;
import com.google.ads.googleads.examples.utils.ArgumentNames;
import com.google.ads.googleads.examples.utils.CodeSampleParams;
import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.ads.googleads.v3.errors.GoogleAdsException;
import com.google.ads.googleads.v3.errors.GoogleAdsError;
import com.google.ads.googleads.v3.resources.AccountBudget;
import com.google.ads.googleads.v3.services.GoogleAdsRow;
import com.google.ads.googleads.v3.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v3.services.GoogleAdsServiceClient.SearchPagedResponse;
import java.io.FileNotFoundException;
import java.io.IOException;

/** Retrieves all account budgets for a Google Ads customer. */
public class GetAccountBudgets {

  private static class GetAccountBudgetParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
    private Long customerId;
  }

  public static void main(String[] args) {
    GetAccountBudgetParams params = new GetAccountBudgetParams();
    if (!params.parseArguments(args)) {

      // Either pass the required parameters for this example on the command line, or insert them
      // into the code here. See the parameter class definition above for descriptions.
      params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE");
    }

    GoogleAdsClient googleAdsClient;
    try {
      googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build();
    } catch (FileNotFoundException fnfe) {
      System.err.printf(
          "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe);
      return;
    } catch (IOException ioe) {
      System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe);
      return;
    }

    try {
      new GetAccountBudgets().runExample(googleAdsClient, params.customerId);
    } catch (GoogleAdsException gae) {
      // GoogleAdsException is the base class for most exceptions thrown by an API request.
      // Instances of this exception have a message and a GoogleAdsFailure that contains a
      // collection of GoogleAdsErrors that indicate the underlying causes of the
      // GoogleAdsException.
      System.err.printf(
          "Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
          gae.getRequestId());
      int i = 0;
      for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
        System.err.printf("  Error %d: %s%n", i++, googleAdsError);
      }
    }
  }

  /**
   * Runs the example.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the customer ID for which to retrieve account budgets.
   */
  private void runExample(GoogleAdsClient googleAdsClient, long customerId) {
    String query =
        "SELECT "
            + "account_budget.status, "
            + "account_budget.billing_setup, "
            + "account_budget.approved_spending_limit_micros, "
            + "account_budget.approved_spending_limit_type, "
            + "account_budget.proposed_spending_limit_micros, "
            + "account_budget.proposed_spending_limit_type, "
            + "account_budget.approved_start_date_time, "
            + "account_budget.proposed_start_date_time, "
            + "account_budget.approved_end_date_time, "
            + "account_budget.approved_end_time_type,"
            + "account_budget.proposed_end_date_time, "
            + "account_budget.proposed_end_time_type "
            + "FROM account_budget";
    try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
      // Issues the search request.
      SearchPagedResponse searchPagedResponse =
          googleAdsServiceClient.search(Long.toString(customerId), query);

      // Iterates over all rows in all pages and prints the requested field values for the account
      // budget in each row.
      for (GoogleAdsRow googleAdsRow : searchPagedResponse.iterateAll()) {
        AccountBudget accountBudget = googleAdsRow.getAccountBudget();

        System.out.printf(
            "Account budget '%s' with "
                + "status '%s' "
                + "billing setup '%s' "
                + "amount served %.2f "
                + "total adjustments %.2f "
                + "approved spending limit '%s' "
                + "(proposed '%s') "
                + "approved start time '%s' "
                + "(proposed '%s') "
                + "approved end time '%s' "
                + "(proposed '%s')"
                + ".%n",
            accountBudget.getResourceName(),
            accountBudget.getStatus(),
            accountBudget.getBillingSetup().getValue(),
            accountBudget.getAmountServedMicros().getValue() / 1_000_000.0,
            accountBudget.getTotalAdjustmentsMicros().getValue() / 1_000_000.0,
            accountBudget.hasApprovedSpendingLimitMicros()
                ? String.format(
                    "%.2f", accountBudget.getApprovedSpendingLimitMicros().getValue() / 1_000_000.0)
                : accountBudget.getApprovedSpendingLimitType().name(),
            accountBudget.hasProposedSpendingLimitMicros()
                ? String.format(
                    "%.2f", accountBudget.getProposedSpendingLimitMicros().getValue() / 1_000_000.0)
                : accountBudget.getProposedSpendingLimitType().name(),
            accountBudget.getApprovedStartDateTime().getValue(),
            accountBudget.getProposedStartDateTime().getValue(),
            accountBudget.hasApprovedEndDateTime()
                ? accountBudget.getApprovedEndDateTime().getValue()
                : accountBudget.getApprovedEndTimeType(),
            accountBudget.hasProposedEndDateTime()
                ? accountBudget.getProposedEndDateTime().getValue()
                : accountBudget.getProposedEndTimeType());
      }
    }
  }
}

Python

#!/usr/bin/env python
# Copyright 2018 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.
"""This illustrates how to get all account budgets for a Google Ads customer."""


import argparse
import sys

from google.ads.google_ads.client import GoogleAdsClient
from google.ads.google_ads.errors import GoogleAdsException


def main(client, customer_id):
    ga_service = client.get_service('GoogleAdsService', version='v3')

    query = ('SELECT account_budget.status, '
             'account_budget.billing_setup, '
             'account_budget.approved_spending_limit_micros, '
             'account_budget.approved_spending_limit_type, '
             'account_budget.proposed_spending_limit_micros, '
             'account_budget.proposed_spending_limit_type, '
             'account_budget.adjusted_spending_limit_micros, '
             'account_budget.adjusted_spending_limit_type, '
             'account_budget.approved_start_date_time, '
             'account_budget.proposed_start_date_time, '
             'account_budget.approved_end_date_time, '
             'account_budget.approved_end_time_type, '
             'account_budget.proposed_end_date_time, '
             'account_budget.proposed_end_time_type '
             'FROM account_budget')

    response = ga_service.search_stream(customer_id, query=query)

    try:
        # Use the enum type to determine the enum names from the values.
        budget_status_enum = client.get_type(
            'AccountBudgetStatusEnum', version='v3').AccountBudgetStatus

        for batch in response:
            for row in batch.results:
                budget = row.account_budget
                approved_spending_limit = (
                    _micros_to_currency(budget.approved_spending_limit_micros.value)
                    if budget.approved_spending_limit_micros
                    else budget.approved_spending_limit_type.name)
                proposed_spending_limit = (
                    _micros_to_currency(budget.proposed_spending_limit_micros.value)
                    if budget.proposed_spending_limit_micros
                    else budget.proposed_spending_limit_type.name)
                adjusted_spending_limit = (
                    _micros_to_currency(budget.adjusted_spending_limit_micros.value)
                    if budget.adjusted_spending_limit_micros
                    else budget.adjusted_spending_limit_type.name)
                approved_end_date_time = (
                    budget.approved_end_date_time.value
                    if budget.approved_end_date_time
                    else budget.approved_end_date_time_type)
                proposed_end_date_time = (
                    budget.proposed_end_date_time.value
                    if budget.proposed_end_date_time
                    else budget.proposed_end_date_time_type)

                print(f'Account budget "{budget.resource_name}", '
                      f'with status "{budget_status_enum.Name(budget.status)}" ',
                      f'billing setup "{budget.billing_setup.value}", '
                      f'amount served {_micros_to_currency(budget.amount_served_micros.value):.2f}, '
                      f'total adjustments {_micros_to_currency(budget.total_adjustments_micros.value):.2f}, '
                      f'approved spending limit "{approved_spending_limit}" '
                      f'(proposed "{proposed_spending_limit}" -- '
                      f'adjusted "{adjusted_spending_limit}"), '
                      f'approved start time "{budget.approved_start_date_time.value}" '
                      f'(proposed "{budget.proposed_start_date_time.value}"), '
                      f'approved end time "{approved_end_date_time}" '
                      f'(proposed "{proposed_end_date_time}").')
    except GoogleAdsException as ex:
        print(f'Request with ID "{ex.request_id}" failed with status '
              f'"{ex.error.code().name}" and includes the following errors:')
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f'\t\tOn field: {field_path_element.field_name}')
        sys.exit(1)


def _micros_to_currency(micros):
    return micros / 1000000.0


if __name__ == '__main__':
    # GoogleAdsClient will read the google-ads.yaml configuration file in the
    # home directory if none is specified.
    google_ads_client = GoogleAdsClient.load_from_storage()

    parser = argparse.ArgumentParser(
        description=('Lists all account budgets for given Google Ads customer '
                     'ID.'))
    # The following argument(s) should be provided to run the example.
    parser.add_argument('-c', '--customer_id', type=str,
                        required=True, help='The Google Ads customer ID.')
    args = parser.parse_args()

    main(google_ads_client, args.customer_id)

Note that fields encapsulating the account budget's start time, end time, and spending limit have multiple variants with prefixes such as proposed and approved that allow for comparing the values that were initially proposed with those that were approved. The spending limit has additional fields with the adjusted prefix to indicate the current spending limit in effect after any adjustments were applied to the approved amount.

An account budget's approved spending limit can be adjusted over time to reflect various credits for things like budget overdelivery, invalid click activity, and promotional coupons. More information about account budgets and account credits and adjustments can be found in the Google Ads Help Center.

Any new account budgets pending approval, along with any existing account budgets that have updates pending, will also contain an account_budget.pending_proposal field that can be selected. It will contain the resource ID of the associated AccountBudgetProposal object.

Managing existing account budgets

After creating an account budget for a customer, you can use the AccountBudgetProposalService to manage the budget parameters. The most common management operations are to update the spending_limit and end_date_time fields. For a complete list of the mutable fields, refer to the AccountBudgetProposal document.

You have the option of updating an existing account budget or creating a entirely new budget, both are shown here.

Update an existing account budget

You can update the existing account budget fields by sending AccountBudgetProposal objects with AccountBudgetProposalType set to UPDATE.

AccountBudgetProposal proposal = AccountBudgetProposal.newBuilder()
  .setProposalType(AccountBudgetProposalType.UPDATE)
  .setAccountBudget(StringValue.of("customers/1234567890/accountBudgets/1"))
  .setProposedSpendingLimitMicros(Int64Value.of(spendingLimit + increaseAmount))
  .setProposedEndDateTime(StringValue.of("2049-01-01"))
  .build();

AccountBudgetProposalOperation.newBuilder()
  .setCreate(proposal)
  .setUpdateMask(
      FieldMask.newBuilder().addAllPaths(Arrays
          .asList("proposed_spending_limit", "proposed_end_date_time")).build())
  .build();

// Send request to Google Ads API (not shown).

Account budget chaining

As an alternative to updating the existing budget, Google Ads allows you to chain multiple account budgets to run in succession. In the following example, a customer has different spending limits each month.

This can be achieved by creating three AccountBudgetProposal objects and sending them to AccountBudgetProposalService.

AccountBudgetProposal proposalMay = AccountBudgetProposal.newBuilder()
  .setBillingSetup(StringValue.of("customer/1234567890/billingSetups/1"))
  .setProposalType(AccountBudgetProposalType.CREATE)
  .setProposedName(StringValue.of("May budget"))
  .setProposedStartDateTime(StringValue.of("2018-05-01"))
  .setProposedEndDateTime(StringValue.of("2018-06-01"))
  .setProposedSpendingLimitMicros(Int64Value.of(1_000_000_000L))
  .build();

AccountBudgetProposal proposalJune = AccountBudgetProposal.newBuilder()
  .setBillingSetup(StringValue.of("customer/1234567890/billingSetups/1"))
  .setProposalType(AccountBudgetProposalType.CREATE)
  .setProposedName(StringValue.of("June budget"))
  .setProposedStartDateTime(StringValue.of("2018-06-01"))
  .setProposedEndDateTime(StringValue.of("2018-07-01"))
  .setProposedSpendingLimitMicros(Int64Value.of(5_000_000_000L))
  .build();

AccountBudgetProposal proposalJuly = AccountBudgetProposal.newBuilder()
  .setBillingSetup(StringValue.of("customer/1234567890/billingSetups/1"))
  .setProposalType(AccountBudgetProposalType.CREATE)
  .setProposedName(StringValue.of("July budget"))
  .setProposedStartDateTime(StringValue.of("2018-07-01"))
  .setProposedEndDateTime(StringValue.of("2018-08-01"))
  .setProposedSpendingLimitMicros(Int64Value.of(1_000_000_000L))
  .build();

// Send request to Google Ads API (not shown).

Note the use of AccountBudgetProposalType= CREATE on each proposal. This will create three distinct budgets, rather than updating the same budget three times.

Terminating account budgets

Account budgets can be ended while active, and removed entirely prior to starting or while pending approval.

Ending the active account budget

The active account budget cannot be removed. However, you can set the end time to the current time. The simplest way to achieve this is to send a proposal with AccountBudgetProposalType= END.

AccountBudgetProposal.newBuilder()
  .setAccountBudget(StringValue.of("customers/1234567890/accountBudgets/1"))
  .setProposalType(AccountBudgetProposalType.END)
  .build();

// Send request to Google Ads API (not shown).

This is equivalent to setting the end date time to NOW, as per:

AccountBudgetProposal proposal = AccountBudgetProposal.newBuilder()
  .setAccountBudget(StringValue.of("customers/9882804443/accountBudgets/476626184"))
  .setProposalType(AccountBudgetProposalType.UPDATE)
  .setProposedEndTimeType(TimeType.NOW)
  .build();

AccountBudgetProposalOperation operation = AccountBudgetProposalOperation.newBuilder()
  .setCreate(proposal)
  .setUpdateMask(
      FieldMask.newBuilder().addAllPaths(Arrays
          .asList("proposed_end_date_time")).build())
  .build();

// Send request to Google Ads API (not shown).

Removing an approved account budget before its start time

If you proposed an account budget to start in future, you can remove this entirely prior to the start time by sending a REMOVE proposal type.

AccountBudgetProposal proposal = AccountBudgetProposal.newBuilder()
  .setAccountBudget(StringValue.of("customers/1234567890/accountBudgets/1"))
  .setProposalType(AccountBudgetProposalType.REMOVE)
  .build();

AccountBudgetProposalOperation operation = AccountBudgetProposalOperation.newBuilder()
  .setCreate(proposal)
  .build();

// Send request to Google Ads API (not shown).

Removing a pending account budget proposal

You can entirely remove a pending budget proposal by setting AccountBudgetProposalType= REMOVE. However bear in mind that budget proposals are usually applied very quickly (minutes) so this will usually not be possible.

AccountBudgetProposalOperation operation = AccountBudgetProposalOperation.newBuilder()
  .setRemove("customers/9882804443/accountBudgetProposal/476626184")
  .build();