Sample custom bidding scripts


return aggregate_function([
 ([criteria_a, criteria_b], score), #criteria1 
 ([criteria_a], score) #criteria2
  • All the criteria must be enclosed in brackets [ ].
  • A comma , is used for and.
  • For criteria1 above to return true, both criteria_a and criteria_b must return true.

Aggregate models

  • sum_aggregate - returns the sum of all criteria that return true.
  • max_aggregate - returns only the value of the true criteria that has the maximum assigned weight.
  • first_match_aggregate - returns the assigned value for the first criteria in the array that returns true.

Use case: Sales Floodlight revenue

return (total_conversion_value(Floodlight_ID, model_id))
  • The script optimizes to the Revenue parameter tracked in a Floodlight Sales tag.
  • Replace Floodlight_ID with your own activity ID.
  • Replace model_id with your Attribution Model ID if you have set up an attribution model at the advertiser level.
    • If you haven't set up a model, set model_id to 0 to use last-touch attribution.

Real world example

An e-commerce advertiser wants to optimize for transaction value (instead of total transactions). You are tracking the checkout confirmation with a Floodlight Sales tag, and a transaction value.

Use case: Weighted conversions with different Floodlights

return sum_aggregate([
        ([total_conversion_count(Floodlight_ID_1, model_id)>0], total_conversion_count(Floodlight_ID_1, model_id)*weighting_1),
        ([total_conversion_count(Floodlight_ID_2, model_id)>0], total_conversion_count(Floodlight_ID_2, model_id)*weighting_2),
        ([total_conversion_count(Floodlight_ID_3, model_id)>0], total_conversion_count(Floodlight_ID_3, model_id)*weighting_3)
  • This script optimizes to 3 different conversions activities, where each activity is worth a different value.
  • If an impression leads to different conversions, the value of the conversions are summed when attributing value to the impression.
  • If an impression leads to multiple conversions for the same activity ID, the number of conversions are summed and then multiplied by the conversion weighting.
  • Replace Floodlight_ID_1, Floodlight_ID_2, Floodlight_ID_3 with your own activity IDs (e.g. 123456, 456789, 78901).
  • Replace model_id with your Attribution Model ID if you have set up an attribution model at the advertiser level
    • If you haven't set up a model, set model_id to 0 to use last-touch attribution
  • Replace weighting_1, weighting_2, weighting_3 with your own weightings (e.g. 100, 5, or 0.2).

Real world examples

  • A car manufacturer is tracking conversions on minivan, SUV, and sedan product pages. To optimize toward value, each of these car categories are assigned different values. 
  • A nonprofit wants to optimize for donation events. Because donation events are very rare, they add in upper-funnel activities (e.g. clicks on “Learn more about the organization” and “See how you can help”) and assign lower weightings to them to drive volume.


  • To change the number of weighted conversion activities, you cab delete or add new conditions.
  • To assign the value of the highest-value conversion event instead of summing the value of multiple conversions, you can change sum_aggregate to max_aggregate.
  • To assign the value of the first matching conversion event (based on the order in your script) use first_match_aggregate.

Variation samples

To assign a higher value to a conversion event, and a lower value to clicks:

return max_aggregate([
    ([click], weight_1),
    ([total_conversion_count(Floodlight_ID_1, model_id)>0], weight_2)

To assigns a higher value to clickthrough conversion events, and a lower value to a viewthrough conversion events:

return sum_aggregate([
    ([click, total_conversion_count(Floodlight_ID_1, model_id)>0], weight_1),
    ([not click, total_conversion_count(Floodlight_ID_1, model_id)>0], weight_2)

Use case: Custom Floodlight variables

_uvar = conversion_custom_variable(Floodlight_ID, model_id, u_variable_index)

if _uvar != None and _uvar != "":
    return float(_uvar)

return 0

  • The script optimizes to a single Custom Floodlight variable for a single Floodlight activity, and values all non-converting impressions as 0.
  • conversion_custom_variable  returns a string (if there's a conversion) or none (if there's no conversion).
  •  Any impression that is not attributed by the model will return as None and be valued as 0.
  • Replace Floodlight_ID with your own activity ID.
  • Replace model_id with your attribution model ID if you have set up an attribution model at the advertiser level.
    • If you haven't set up a model, set model_id to 0 to use last-touch attribution.
  • Replace u_variable_index with your own Custom Floodlight u-variable index (e.g. 3) for your activity ID.
  • When using u-variables in custom bidding scripts, they must be shared with Display & Video 360 first. To do this:
    1. Navigate to Resourcesand then Floodlight Group and then [select Floodlight] and then Custom Floodlight variables.
    2. Check the box next to the u-variable used in the script,

Real world example

A car rental chain wants to optimize for the number of vehicle reservations. The reservation confirmation activity is tracked in a Floodlight, and the number of nights booked in a Custom Floodlight variable.

Use case: Using Google Analytics 360 goals

You will need to first link the Google Analytics 360 account with the Display & Video 360 advertiser, then create goals within the Google Analytics 360 account. When linking a Google Analytics 360 account with Display & Video 360 for custom bidding, you are sharing conversion data, which will only be available in Display & Video 360 custom bidding metrics through reporting. Make sure the linked accounts are sharing data and have goals in place. Scripts not using Google Analytics 360 goals will not score impressions.

Google Analytics 360 goals require a click, so make sure there's sufficient data to generate a model. To check the volume of data, pull a report in the Google Analytics 360 account. To see the amount of goal events based on the last non-direct click model (GA model), within Google Analytics 360 navigate to Acquisition > All Traffic > Source/Medium report and filter for dbm / cpm

Optimizing for a single Google Analytics 360 goal

Assume you want to optimize to users who have spent longer than 30 seconds on a page. First, you would set up a duration goal in Google Analytics 360 and take note of the View ID and Goal ID.

return has_ga_goal(GA View ID, GA Goal ID)

  •  If has_ga_goal(GA View ID, GA Goal ID) returns true, it will return 1. If it is false, it will return 0. 

Optimizing using combinations of Google Analytics 360 goals (weighted)

Assume you want to optimize for specific user paths on your site using Google Analytics 360 Funnel Destination paths. You value one path twice as much as the other, because this user shows a greater affinity for the brand.

The first Google Analytics Goal (GA View ID, GA Goal ID) e.g. (111,222) = half the value of the second Google Analytics Goal e.g. (333,444).

return sum_aggregate([

        ([has_ga_goal(111, 222)], ga_goals_count(111, 222)),

        ([has_ga_goal(333, 444)], ga_goals_count(333, 444)*2)


Optimizing towards the value passed alongside the Google Analytics goal (ROAS)

Assume you want to maximize the basket return from users who have visited more than 5 pages in a session using a Google Analytics 360 session goal. They are keen clients likely to return, but you still want to maximize your return on spend.

if ga_goals_count(111, 222)>5:

 return ga_goals_total_value(111, 222)


 return 0

Was this helpful?
How can we improve it?

Need more help?

Sign in for additional support options to quickly solve your issue