Features
Prevents budget waste on underutilized campaigns while scaling spend for constrained high-performers.
✓ Campaigns hitting daily budget caps that need automated scaling when performance justifies increased spend
✓ Overbudgeted campaigns wasting potential by having daily budgets far above actual spend patterns
✓ Data-starved campaigns with budgets too low to generate the minimum clicks needed for optimization decisions
✓ Accounts wanting hands-off budget management that adapts to both growth opportunities and efficiency improvements
Daily or Multiple Times Daily | Automation: Change Daily Budget: Set ($) using $new_budget
Run multiple times daily during high-traffic periods to catch budget constraints quickly, or daily for standard monitoring.
The blueprint operates two independent decision paths that never conflict. The increase path examines the last four individual days to detect budget-capping behavior, then verifies performance is acceptable before scaling up by a fixed percentage. The rightsizing path analyzes sustained 14-day average utilization to identify campaigns consistently spending well below budget, then calculates a new budget based on actual usage patterns plus a buffer. A third "data starvation" path increases budgets that fall below CPC-based minimums regardless of utilization, ensuring all campaigns can generate enough clicks for reliable optimization.
Individual Daily Budget Cap Detection
Most budget management tools look at average utilization, which can hide intermittent constraints. This blueprint checks each of the last four days individually - if ANY single day hit 90%+ utilization and ACOS is acceptable, it triggers an increase. This catches scenarios like weekend budget caps that disappear into weekday averages, or campaigns that only hit caps on high-traffic days. One capped day in the last four is treated as evidence of constraint.
CPC-Based Data Minimum System
The blueprint calculates a dynamic minimum budget using your average CPC × minimum daily clicks (default 5). A campaign averaging $0.50 CPC needs at least $2.50 daily budget to support data collection. This minimum applies to both rightsizing decreases and data-starvation increases, creating a floor that ensures campaigns remain optimizable. Campaigns below this floor trigger immediate increases regardless of utilization or performance.
Sustained Utilization for Rightsizing
Unlike the increase path which reacts to single-day caps, rightsizing requires sustained 14-day average utilization below 50%. This asymmetry is intentional - increases should be reactive (quick response to constraints) while decreases should be conservative (only act on persistent underutilization). A campaign spending $8/day against a $20 budget for two full weeks triggers rightsizing, but two low-spend days mixed with normal days won't.
Performance-Gated Increases with Data Tolerance
Budget increases require ACOS ≤ 130% of target across three cascading periods (7d → 14d → 30d). However, if no period has sufficient orders for reliable ACOS ($orders_min = 4), the blueprint allows the increase anyway. This "innocent until proven guilty" approach recognizes that budget constraints themselves may be preventing the order volume needed for ACOS evaluation. If you're capped and can't evaluate performance, the blueprint gives you room to generate data.
Dual Minimum Logic
The blueprint uses different minimum floors for increases vs decreases:
This ensures rightsizing never creates data starvation, while still allowing performance-based increases to start from the platform floor.
Utilization Threshold Interaction
The 90% high and 50% low thresholds create three zones:
Narrowing this acceptable range (e.g., 70-85%) increases budget turnover - more frequent increases and decreases as campaigns move in/out of the target zone. Widening it (e.g., 40-95%) creates more stability but may leave efficiency on the table. Consider your management bandwidth and campaign predictability when tuning.
Orders Minimum for ACOS Evaluation
The $orders_min = 4 setting determines when ACOS is considered reliable for gating increases. This is intentionally higher than typical ACOS evaluation minimums (usually 2) because you're making spending decisions, not just bid adjustments. Lower values (2-3) make the ACOS gate easier to pass, enabling more budget increases. Higher values (5-6) require more proof of efficiency before scaling spend. If you're seeing too many increases on questionable performers, increase this threshold.
Spend Buffer for Rightsizing
When rightsizing, the new budget is set to average daily spend × $spend_buffer (default 130%). This 30% cushion prevents setting budgets so tight that campaigns immediately hit caps again due to natural daily variance. Reducing to 110-120% creates tighter budgets that maximize efficiency but risk constraint on above-average days. Increasing to 150%+ provides more breathing room but may leave excess budget unused. The 130% default is designed for typical daily spend variance of ±20%.
Budget Increase Percentage Scaling
The fixed 20% increase ($budget_increase_pct) is conservative by design - it takes 4-5 iterations to double a budget. Increase to 30-50% if you want faster scaling on proven performers (useful during launch periods or seasonal ramps). Decrease to 10-15% if you want more gradual, cautious scaling. Avoid increases above 50% as this can create budget shock if ACOS subsequently degrades.
Cooldown Period Strategy
The 14-day cooldown between rightsizing actions prevents thrashing on campaigns with variable spend. Campaigns that occasionally spike above the low utilization threshold won't immediately trigger re-increases after being rightsized. If your campaigns have predictable, stable spend patterns, you can safely shorten to 7 days. If you see rightsizing → increase → rightsizing cycles, extend to 21-30 days or raise the low utilization threshold.
$reason Utilization Ranges:
The diagnostic includes actual average utilization ranges in brackets:
These ranges help you understand not just that action is/isn't being taken, but how far from thresholds each campaign sits.
Reason Categories:
$result Action Types:
Rapid Budget-Capping Increases
Campaigns consistently showing "Budget Increase: High Utilization" across consecutive days are successfully scaling but may be hitting caps again immediately after each increase. This is normal during high-performance periods - the 20% increases are intentionally conservative. If you want faster scaling on these proven winners, increase $budget_increase_pct to 30-40%. Alternatively, manually set budgets higher on your top performers and let automation manage the rest.
Data-Starved Campaign Recovery
Campaigns showing "Budget Increase: CPC Minimum" had budgets below what's needed for basic data collection. After increase, watch for them to transition to utilization-based decisions within 1-2 weeks. If campaigns remain stuck on CPC minimums long-term (still showing 0-10% utilization after increases), they may have fundamental performance issues preventing any meaningful spend. Consider pausing these rather than continuing to maintain minimum budgets.
Rightsizing Followed by Stability
Campaigns showing "Budget Decrease: Rightsizing" should then show "Within acceptable utilization" after the decrease. If you see a campaign rightsize, then immediately trigger "Budget Increase: High Utilization" within a few days, your thresholds are too close together (50% low and 90% high might be creating boundary cases). Either raise the low threshold to 60% or lower the high threshold to 85% to create more separation.
Cooldown Blocking Obvious Rightsizing
Campaigns showing "[0-30%] Below low utilization threshold, cooldown active" for extended periods suggest the 14-day cooldown is too long for your account's spend patterns. These campaigns are clearly underutilizing budget but waiting on cooldown. If this is common, reduce $cooldown_period to 7 days, or if you're confident in the stability of these campaigns, manually reduce their budgets and let automation take over after cooldown.
ACOS Blocking Scale Opportunities
Campaigns showing "[90%+] Above high utilization threshold, ACOS too high" are budget-capped but performing poorly. This is the blueprint correctly preventing bad spend scaling. However, if you see this frequently and believe the campaigns deserve scale opportunities, either: (1) loosen $t_acos_threshold_increase to 150-200% to allow scaling on less efficient campaigns, or (2) use bid management automation to improve ACOS first, then let budget scaling follow.
Minimum Floor Preventing Rightsizing
Campaigns showing "Budget below rightsizing minimum" at 0-30% utilization are already at the calculated minimum (either $budget_min = $5.00 or CPC-based minimum). If you have many campaigns stuck here, consider whether you actually need them active. Campaigns that can't productively spend even $5/day may be better candidates for pausing rather than maintaining minimum budgets indefinitely. Alternatively, if you want more aggressive rightsizing, lower $budget_min to $3.00 or disable CPC minimums (though this risks data starvation).
/*
=== Core: Adaptive Budget Management ===
Purpose: Prevents budget waste while ensuring adequate spend for data collection and performance scaling.
Recommended: Change Daily Budget | Set ($) using $new_budget | Daily or Multiple Times Daily
*/
// === Core Settings ===
let $high_utilization = 90%; // CORE: Daily spend % that indicates budget constraint
let $low_utilization = 50%; // CORE: Daily budget utilization % that triggers rightsizing
let $enable_cpc_minimums = 1; // ADVANCED: Enable CPC-based budget minimums (1=yes, 0=no)
// === Budget Increases (High Utilization) ===
let $t_acos_threshold_increase = 130%; // STRATEGY: Increase budget when ACOS ≤ (Target ACOS × 130%) [e.g., 30% target = 39% threshold]
let $budget_increase_pct = 20%; // STRATEGY: Percentage increase when scaling up
let $orders_min = 4; // STRATEGY: Minimum orders needed for reliable ACOS evaluation
let $acos_eval_short = 7d; // TIME: Recent performance period
let $acos_eval_medium = 14d; // TIME: Medium-term performance period
let $acos_eval_long = 30d; // TIME: Long-term performance period
// === Budget Rightsizing (Low Utilization) ===
let $spend_buffer = 130%; // STRATEGY: Buffer above avg daily spend when rightsizing (budget set to 130% avg daily spend)
let $budget_min = 5.00; // STRATEGY: Absolute minimum budget floor for rightsizing
let $cooldown_eval_period = 14d; // TIME: Period for sustained utilization evaluation
let $cooldown_period = 14d; // TIME: Wait period between rightsizing actions
// === CPC-Based Budget Minimums ===
let $min_daily_clicks = 5; // ADVANCED: Minimum clicks per day budget should support
let $cpc_eval_period = 60d; // ADVANCED: Period for calculating average CPC for minimum budget
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Increase Path: Individual daily budget cap analysis
let $today_spend = spend(0d..0d);
let $yesterday_spend = spend(1d..1d);
let $day2_spend = spend(2d..2d);
let $day3_spend = spend(3d..3d);
let $today_capped = case($today_spend >= budget * $high_utilization => 1, else 0);
let $yesterday_capped = case($yesterday_spend >= budget * $high_utilization => 1, else 0);
let $day2_capped = case($day2_spend >= budget * $high_utilization => 1, else 0);
let $day3_capped = case($day3_spend >= budget * $high_utilization => 1, else 0);
let $any_day_budget_capped = case(
$today_capped = 1 or $yesterday_capped = 1 or $day2_capped = 1 or $day3_capped = 1 => 1,
else 0
);
// Increase Path: CPC-based data sufficiency check
let $avg_cpc = cpc($cpc_eval_period);
let $min_budget_for_data = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 => $avg_cpc * $min_daily_clicks,
else 0 // Data minimums disabled or no CPC data
);
let $budget_too_small = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 and budget < $min_budget_for_data => 1,
else 0
);
// Increase Path: Performance evaluation for increases (prioritize recent data)
let $orders_short = orders($acos_eval_short);
let $orders_medium = orders($acos_eval_medium);
let $orders_long = orders($acos_eval_long);
let $performance_acos = case(
$orders_short >= $orders_min => acos($acos_eval_short),
$orders_medium >= $orders_min => acos($acos_eval_medium),
$orders_long >= $orders_min => acos($acos_eval_long),
else 99999 // No reliable ACOS data
);
let $acos_good_for_increase = case(
$performance_acos = 99999 => 1, // No ACOS data = allow increase
target acos <= 0 => 0, // Invalid target
$performance_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// Rightsizing Path: Sustained utilization analysis
let $total_spend = spend($cooldown_eval_period);
let $days_in_eval = 14; // Days in 14d period
let $avg_daily_spend = $total_spend / $days_in_eval;
let $avg_utilization_rate = case(
budget > 0 => $avg_daily_spend / budget,
else 0
);
// Calculate effective minimum for decreases early
let $effective_min_for_decreases = case(
$min_budget_for_data > $budget_min => $min_budget_for_data, // Use CPC minimum if higher
else $budget_min // Otherwise use absolute minimum
);
let $rightsizing_cooldown_passed = case(
is_null(last budget change) => 1,
last budget change < now() - interval($cooldown_period) => 1,
else 0
);
// Decision logic by path
let $should_increase = case(
$budget_too_small = 1 => 1, // Data-starved campaign
$any_day_budget_capped = 1 and $acos_good_for_increase = 1 => 1, // Budget-capped + good performance
else 0
);
let $should_rightsize = case(
$rightsizing_cooldown_passed = 0 => 0, // Cooldown period active
budget <= $effective_min_for_decreases => 0, // Already at or below minimum - don't rightsize
$avg_utilization_rate < $low_utilization => 1, // Sustained low utilization (including 0% from no spend)
else 0
);
// Calculate new budget
let $increase_budget = budget * (1 + $budget_increase_pct);
// For rightsizing, calculate based on actual usage plus buffer
let $rightsized_budget = case(
$avg_daily_spend > 0 => $avg_daily_spend * $spend_buffer,
else $budget_min // No spend = use minimum budget
);
let $calculated_budget = case(
$should_increase = 1 => $increase_budget,
$should_rightsize = 1 => $rightsized_budget,
else budget
);
// Apply minimums - different rules for increases vs decreases
let $final_minimum = case(
$should_rightsize = 1 => case(
$effective_min_for_decreases > 1.00 => $effective_min_for_decreases, // Use effective minimum if higher than platform
else 1.00 // Otherwise platform minimum
),
$should_increase = 1 and $budget_too_small = 1 => case(
$min_budget_for_data > 1.00 => $min_budget_for_data, // Use CPC minimum for data generation increases
else 1.00 // Platform minimum
),
else 1.00 // Platform minimum for budget-capping increases
);
let $new_budget = case(
$calculated_budget < $final_minimum => $final_minimum,
else $calculated_budget
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$should_increase = 1 and $budget_too_small = 1 => case(
$avg_utilization_rate <= 0.10 => "[0-10%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.70 => "[50-70%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.90 => "[70-90%] Below CPC minimum threshold",
else "[90%+] Below CPC minimum threshold"
),
$should_increase = 1 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS acceptable",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS acceptable",
else "[90%+] Above high utilization threshold, ACOS acceptable"
),
$rightsizing_cooldown_passed = 0 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold, cooldown active",
else "[50%+] Below low utilization threshold, cooldown active"
),
$should_rightsize = 1 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold",
else "[50-70%] Below low utilization threshold"
),
$any_day_budget_capped = 1 and $acos_good_for_increase = 0 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS too high",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS too high",
else "[90%+] Above high utilization threshold, ACOS too high"
),
budget <= $effective_min_for_decreases => case(
$avg_utilization_rate = 0 => "[0%] Budget below rightsizing minimum",
$avg_utilization_rate <= 0.30 => "[0-30%] Budget below rightsizing minimum",
else "[30-50%] Budget below rightsizing minimum"
),
else case(
$avg_utilization_rate = 0 => "[0%] Within acceptable utilization",
$avg_utilization_rate <= 0.10 => "[0-10%] Within acceptable utilization",
$avg_utilization_rate <= 0.30 => "[10-30%] Within acceptable utilization",
$avg_utilization_rate <= 0.50 => "[30-50%] Within acceptable utilization",
$avg_utilization_rate <= 0.70 => "[50-70%] Within acceptable utilization",
$avg_utilization_rate <= 0.90 => "[70-90%] Within acceptable utilization",
else "[90%+] Within acceptable utilization"
)
);
let $result = case(
$should_increase = 1 and $budget_too_small = 1 => "Budget Increase: CPC Minimum",
$should_increase = 1 => "Budget Increase: High Utilization",
$should_rightsize = 1 => "Budget Decrease: Rightsizing",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and ($should_increase = 1 or $should_rightsize = 1)
and $new_budget != budget
/*
=== Core: Adaptive Budget Management ===
Purpose: Prevents budget waste while ensuring adequate spend for data collection and performance scaling.
Recommended: Change Daily Budget | Set ($) using $new_budget | Daily or Multiple Times Daily
*/
// === Core Settings ===
let $high_utilization = 90%; // CORE: Daily spend % that indicates budget constraint
let $low_utilization = 50%; // CORE: Daily budget utilization % that triggers rightsizing
let $enable_cpc_minimums = 1; // ADVANCED: Enable CPC-based budget minimums (1=yes, 0=no)
// === Budget Increases (High Utilization) ===
let $t_acos_threshold_increase = 130%; // STRATEGY: Increase budget when ACOS ≤ (Target ACOS × 130%) [e.g., 30% target = 39% threshold]
let $budget_increase_pct = 20%; // STRATEGY: Percentage increase when scaling up
let $orders_min = 4; // STRATEGY: Minimum orders needed for reliable ACOS evaluation
let $acos_eval_short = 7d; // TIME: Recent performance period
let $acos_eval_medium = 14d; // TIME: Medium-term performance period
let $acos_eval_long = 30d; // TIME: Long-term performance period
// === Budget Rightsizing (Low Utilization) ===
let $spend_buffer = 130%; // STRATEGY: Buffer above avg daily spend when rightsizing (budget set to 130% avg daily spend)
let $budget_min = 5.00; // STRATEGY: Absolute minimum budget floor for rightsizing
let $cooldown_eval_period = 14d; // TIME: Period for sustained utilization evaluation
let $cooldown_period = 14d; // TIME: Wait period between rightsizing actions
// === CPC-Based Budget Minimums ===
let $min_daily_clicks = 5; // ADVANCED: Minimum clicks per day budget should support
let $cpc_eval_period = 60d; // ADVANCED: Period for calculating average CPC for minimum budget
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Increase Path: Individual daily budget cap analysis
let $today_spend = spend(0d..0d);
let $yesterday_spend = spend(1d..1d);
let $day2_spend = spend(2d..2d);
let $day3_spend = spend(3d..3d);
let $today_capped = case($today_spend >= budget * $high_utilization => 1, else 0);
let $yesterday_capped = case($yesterday_spend >= budget * $high_utilization => 1, else 0);
let $day2_capped = case($day2_spend >= budget * $high_utilization => 1, else 0);
let $day3_capped = case($day3_spend >= budget * $high_utilization => 1, else 0);
let $any_day_budget_capped = case(
$today_capped = 1 or $yesterday_capped = 1 or $day2_capped = 1 or $day3_capped = 1 => 1,
else 0
);
// Increase Path: CPC-based data sufficiency check
let $avg_cpc = cpc($cpc_eval_period);
let $min_budget_for_data = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 => $avg_cpc * $min_daily_clicks,
else 0 // Data minimums disabled or no CPC data
);
let $budget_too_small = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 and budget < $min_budget_for_data => 1,
else 0
);
// Increase Path: Performance evaluation for increases (prioritize recent data)
let $orders_short = orders($acos_eval_short);
let $orders_medium = orders($acos_eval_medium);
let $orders_long = orders($acos_eval_long);
let $performance_acos = case(
$orders_short >= $orders_min => acos($acos_eval_short),
$orders_medium >= $orders_min => acos($acos_eval_medium),
$orders_long >= $orders_min => acos($acos_eval_long),
else 99999 // No reliable ACOS data
);
let $acos_good_for_increase = case(
$performance_acos = 99999 => 1, // No ACOS data = allow increase
target acos <= 0 => 0, // Invalid target
$performance_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// Rightsizing Path: Sustained utilization analysis
let $total_spend = spend($cooldown_eval_period);
let $days_in_eval = 14; // Days in 14d period
let $avg_daily_spend = $total_spend / $days_in_eval;
let $avg_utilization_rate = case(
budget > 0 => $avg_daily_spend / budget,
else 0
);
// Calculate effective minimum for decreases early
let $effective_min_for_decreases = case(
$min_budget_for_data > $budget_min => $min_budget_for_data, // Use CPC minimum if higher
else $budget_min // Otherwise use absolute minimum
);
let $rightsizing_cooldown_passed = case(
is_null(last budget change) => 1,
last budget change < now() - interval($cooldown_period) => 1,
else 0
);
// Decision logic by path
let $should_increase = case(
$budget_too_small = 1 => 1, // Data-starved campaign
$any_day_budget_capped = 1 and $acos_good_for_increase = 1 => 1, // Budget-capped + good performance
else 0
);
let $should_rightsize = case(
$rightsizing_cooldown_passed = 0 => 0, // Cooldown period active
budget <= $effective_min_for_decreases => 0, // Already at or below minimum - don't rightsize
$avg_utilization_rate < $low_utilization => 1, // Sustained low utilization (including 0% from no spend)
else 0
);
// Calculate new budget
let $increase_budget = budget * (1 + $budget_increase_pct);
// For rightsizing, calculate based on actual usage plus buffer
let $rightsized_budget = case(
$avg_daily_spend > 0 => $avg_daily_spend * $spend_buffer,
else $budget_min // No spend = use minimum budget
);
let $calculated_budget = case(
$should_increase = 1 => $increase_budget,
$should_rightsize = 1 => $rightsized_budget,
else budget
);
// Apply minimums - different rules for increases vs decreases
let $final_minimum = case(
$should_rightsize = 1 => case(
$effective_min_for_decreases > 1.00 => $effective_min_for_decreases, // Use effective minimum if higher than platform
else 1.00 // Otherwise platform minimum
),
$should_increase = 1 and $budget_too_small = 1 => case(
$min_budget_for_data > 1.00 => $min_budget_for_data, // Use CPC minimum for data generation increases
else 1.00 // Platform minimum
),
else 1.00 // Platform minimum for budget-capping increases
);
let $new_budget = case(
$calculated_budget < $final_minimum => $final_minimum,
else $calculated_budget
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$should_increase = 1 and $budget_too_small = 1 => case(
$avg_utilization_rate <= 0.10 => "[0-10%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.70 => "[50-70%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.90 => "[70-90%] Below CPC minimum threshold",
else "[90%+] Below CPC minimum threshold"
),
$should_increase = 1 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS acceptable",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS acceptable",
else "[90%+] Above high utilization threshold, ACOS acceptable"
),
$rightsizing_cooldown_passed = 0 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold, cooldown active",
else "[50%+] Below low utilization threshold, cooldown active"
),
$should_rightsize = 1 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold",
else "[50-70%] Below low utilization threshold"
),
$any_day_budget_capped = 1 and $acos_good_for_increase = 0 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS too high",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS too high",
else "[90%+] Above high utilization threshold, ACOS too high"
),
budget <= $effective_min_for_decreases => case(
$avg_utilization_rate = 0 => "[0%] Budget below rightsizing minimum",
$avg_utilization_rate <= 0.30 => "[0-30%] Budget below rightsizing minimum",
else "[30-50%] Budget below rightsizing minimum"
),
else case(
$avg_utilization_rate = 0 => "[0%] Within acceptable utilization",
$avg_utilization_rate <= 0.10 => "[0-10%] Within acceptable utilization",
$avg_utilization_rate <= 0.30 => "[10-30%] Within acceptable utilization",
$avg_utilization_rate <= 0.50 => "[30-50%] Within acceptable utilization",
$avg_utilization_rate <= 0.70 => "[50-70%] Within acceptable utilization",
$avg_utilization_rate <= 0.90 => "[70-90%] Within acceptable utilization",
else "[90%+] Within acceptable utilization"
)
);
let $result = case(
$should_increase = 1 and $budget_too_small = 1 => "Budget Increase: CPC Minimum",
$should_increase = 1 => "Budget Increase: High Utilization",
$should_rightsize = 1 => "Budget Decrease: Rightsizing",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and ($should_increase = 1 or $should_rightsize = 1)
and $new_budget != budget
Scales bid adjustments proportionally based on distance from target ACOS using adaptive timing controls.
✓ Accounts wanting intelligent bid optimization that adjusts more aggressively when performance is far from target and more cautiously when close
✓ Keywords and targets with varying data reliability where some have daily orders while others need weeks to generate meaningful signals
✓ Sellers who want proportional responses rather than binary "increase or decrease" logic that treats all performance gaps the same
✓ Accounts ready for sophisticated automation that adapts cooldown periods based on data freshness and volume
Daily | Automation: Change Bid: Set ($) using $target_bid
Scales bid adjustments proportionally based on distance from target ACOS using adaptive timing controls.
✓ Accounts wanting intelligent bid optimization that adjusts more aggressively when performance is far from target and more cautiously when close
✓ Keywords and targets with varying data reliability where some have daily orders while others need weeks to generate meaningful signals
✓ Sellers who want proportional responses rather than binary "increase or decrease" logic that treats all performance gaps the same
✓ Accounts ready for sophisticated automation that adapts cooldown periods based on data freshness and volume
Daily | Automation: Change Bid: Set ($) using $target_bid
The blueprint evaluates performance across four cascading time periods to find the freshest data with sufficient orders, then calculates how far current ACOS is from target ACOS. This distance determines both the magnitude of bid adjustment (closer = smaller changes, farther = larger changes) and the cooldown period before the next change (fresher data = shorter cooldowns). The proportional scaling system creates smooth, graduated responses rather than binary reactions, while buffer zones prevent adjustment churn on keywords performing near target.
Proportional Performance Gap Calculation
The blueprint doesn't treat a keyword at 15% ACOS the same as one at 25% when target is 30%. It calculates exactly how far performance is from the relevant threshold, then scales the adjustment percentage proportionally within your configured min/max range. A keyword barely outside the buffer zone gets close to $bid_min_change (3%), while a keyword at or beyond the max threshold gets the full $bid_max_change (10%). This creates nuanced responses that match the severity of the performance gap.
Four-Tier Data Cascade with Adaptive Cooldowns
The blueprint evaluates four periods in order: 7-day → 14-day → 30-day → 60-day, stopping at the first period with sufficient orders ($orders_min = 2). But it doesn't just use different data - it also adapts the cooldown period based on which tier is used. Fresh 7-day data gets a 2-day cooldown, while old 60-day data gets a 7-day cooldown. This prevents over-optimization when forced to use stale data due to low order volume.
Dual-Threshold Asymmetric System
The blueprint uses different threshold distances for increases vs decreases:
This asymmetry reflects different risk profiles - being very efficient (50% of target) justifies aggressive scaling, while being very inefficient (200% of target) requires aggressive cuts. The buffer zone (90-110% of target by default) sits in the middle, creating a stability zone where no changes occur.
Buffer Zone vs Threshold Logic
Understanding the three zones is critical:
This creates five distinct response regions: max increase, scaled increase, no change, scaled decrease, max decrease.
Buffer and Threshold Interaction
The buffer (tacosbufferminchange)andthresholds(t_acos_buffer_min_change) and thresholds (tacosbufferminchange)andthresholds(t_acos_threshold_max_increase, $t_acos_threshold_max_decrease) work together to create the adjustment curve. If you widen the buffer to 15%, you're creating a 85-115% no-change zone, which means adjustments only start when performance is more significantly different from target. This is paired with threshold distances - if your max increase threshold is 50%, the scaling region runs from 85% down to 50% of target ACOS. Narrower buffers + distant thresholds = more gradual scaling. Wider buffers + close thresholds = more aggressive scaling once outside the buffer.
Data Reliability vs Coverage Tradeoff
Setting $orders_min higher (3-4) means you'll rely on longer lookback periods more often, which increases cooldowns and reduces adjustment frequency but improves confidence in each decision. Setting it lower (2 or even 1) means you'll use fresher data more often, enabling more frequent adjustments but with higher risk of reacting to statistical noise. For accounts with high order volume, consider $orders_min = 3-4. For lower volume accounts where most keywords rarely hit 2 orders in 7 days, keeping it at 2 maximizes coverage.
Adjustment Range Philosophy
The min/max range creates bounds for the proportional scaling. A 3-10% range means:
Narrower ranges (2-7%) create more predictable, conservative automation. Wider ranges (5-15%) create more dramatic responses to performance extremes. Avoid ranges where min is too close to max (like 8-10%) as this eliminates the benefits of proportional scaling.
CPC Limit Period Selection
The $bid_limit_cpc_period = 90d uses a long period to smooth out CPC volatility and establish a stable benchmark. Shortening this to 30-60 days makes the limit more responsive to recent CPC changes (useful if your category sees seasonal CPC shifts), but also makes it more volatile. Lengthening to 180+ days creates extreme stability but may lag behind market changes. The 90-day default balances stability with reasonable responsiveness.
$data_quality Values:
These tags appear in the $reason diagnostic to show both why action is/isn't being taken AND which data quality tier is driving decisions.
$reason Patterns:
$result Magnitude Categories:
High-Volume Keywords with Short Lookback
Keywords consistently showing "High Volume: Short Lookback" are your most actively managed terms. They generate enough orders weekly to use fresh 7-day data with 2-day cooldowns, meaning they can be adjusted multiple times per week if performance shifts. These should show the most responsive bid optimization and are where the proportional scaling system shines most - small performance deviations get small adjustments, large deviations get large adjustments, all happening quickly.
Low-Volume Keywords Stuck on Extended Lookback
Keywords consistently showing "Very Low Volume: Extended Lookback" generate fewer than 2 orders in 30 days, forcing the system to use 60-day data with 7-day cooldowns. These will adjust infrequently (maximum once per week), and when they do adjust, the changes are based on very old data. This is working as designed - low-order keywords should change cautiously. If you're seeing too many keywords stuck here and want more frequent adjustments, lower $orders_min to 1 (but expect more noise).
Buffer Zone Stability vs Constant Adjustments
Keywords bouncing between "Within target buffer zone" and "ACOS below/above target threshold" indicate you're near the buffer boundaries. If you're seeing excessive adjustment churn (adjust up, then down, then up again), widen the buffer to 15% to create more stability. If you're seeing too many keywords sitting in "Within target buffer zone" while you think they should be adjusted, narrow the buffer to 5% to reduce the no-change zone.
CPC Limit Constraints
If many keywords show "Limited by CPC-based maximum" frequently, your bid calculations are trying to exceed 2× average CPC regularly. This suggests either: (1) Your ACOS targets are very aggressive relative to current CPC reality, requiring unrealistic bids to achieve them, or (2) The multiplier is too conservative for your category. Review actual performance of keywords hitting this limit - if they're delivering good ACOS even at the capped bid, consider increasing the multiplier to 2.5 or 3.0.
Cooldown Blocking High-Opportunity Keywords
Keywords showing "[High Volume: Short Lookback] Recently changed - cooldown active" with excellent ACOS (far below target) are in a scenario where you'd like to increase bids more aggressively but the adaptive cooldown is holding you back. This is intentional safety - even with fresh data, some cooldown prevents over-reaction to short-term spikes. However, if you're consistently seeing opportunities blocked by cooldowns, you can shorten the tier-specific cooldown periods ($cooldown_short, $cooldown_medium, etc.) to enable more frequent adjustments.
/*
=== Core: Dynamic Bid Management ===
Purpose: Intelligent bid optimization that adjusts more aggressively when further from target ACOS, with adaptive timing controls.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable ACOS evaluation
let $bid_min_change = 3%; // CORE: Minimum bid adjustment when change is warranted
let $bid_max_change = 10%; // CORE: Maximum bid adjustment when ACOS is at or beyond target ACOS thresholds
// === Target ACOS Thresholds ===
// Between buffer and thresholds: bid adjustments scale linearly from min to max change percent
let $t_acos_buffer_min_change = 10%; // STRATEGY: No-change buffer around target ACOS - min changes start outside this zone (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]
let $t_acos_threshold_max_increase = 50%; // STRATEGY: Max increase when ACOS ≤ (Target ACOS × 50%) [e.g., 30% target = 15% max increase threshold]
let $t_acos_threshold_max_decrease = 200%; // STRATEGY: Max decrease when ACOS ≥ (Target ACOS × 200%) [e.g., 30% target = 60% max decrease threshold]
// === Time Periods ===
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $cooldown_short = 2d; // TIME: Wait period after bid change for short data periods
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $cooldown_medium = 3d; // TIME: Wait period after bid change for medium data periods
let $period_long = 0d..30d; // TIME: Tertiary evaluation period (30 days including today)
let $cooldown_long = 5d; // TIME: Wait period after bid change for long data periods
let $period_extended = 0d..60d; // TIME: Final fallback evaluation period (60 days including today)
let $cooldown_extended = 7d; // TIME: Wait period after bid change for extended data periods
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Multi-period data selection with extended coverage
let $orders_short = orders($period_short);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $orders_extended = orders($period_extended);
let $evaluation_acos = case(
$orders_short >= $orders_min => acos($period_short),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
$orders_extended >= $orders_min => acos($period_extended),
else 99999 // No reliable data
);
// Track which period was used for diagnostics
let $data_quality = case(
$orders_short >= $orders_min => "High Volume: Short Lookback",
$orders_medium >= $orders_min => "Med Volume: Medium Lookback",
$orders_long >= $orders_min => "Low Volume: Long Lookback",
$orders_extended >= $orders_min => "Very Low Volume: Extended Lookback",
else "insufficient"
);
// Adaptive cooldown periods based on data source
let $cooldown_cutoff = case(
$orders_short >= $orders_min => now() - interval($cooldown_short),
$orders_medium >= $orders_min => now() - interval($cooldown_medium),
$orders_long >= $orders_min => now() - interval($cooldown_long),
else now() - interval($cooldown_extended)
);
// Calculate performance ratio with Target ACOS validation
let $acos_ratio = case(
$evaluation_acos = 99999 => -1, // No reliable data
target acos <= 0 => -1, // Invalid target ACOS
else $evaluation_acos / target acos // Performance ratio
);
// Check if within no-change buffer zone
let $within_buffer = case(
$acos_ratio < 0 => 1, // No change if no data or invalid target
$acos_ratio >= (1 - $t_acos_buffer_min_change) and $acos_ratio <= (1 + $t_acos_buffer_min_change) => 1,
else 0
);
// Proportional scaling for bid adjustments
let $performance_gap = case(
$acos_ratio < 0 => 0, // No gap if no data
// Max increase region: ACOS at 50% of target or better
$acos_ratio <= $t_acos_threshold_max_increase => 1,
// Scaled increase region: ACOS between 50% and buffer zone (90% of target)
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
((1 - $t_acos_buffer_min_change) - $acos_ratio) /
((1 - $t_acos_buffer_min_change) - $t_acos_threshold_max_increase),
// Max decrease region: ACOS at 200% of target or worse
$acos_ratio >= $t_acos_threshold_max_decrease => 1,
// Scaled decrease region: ACOS between buffer zone (110%) and 200% of target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
($acos_ratio - (1 + $t_acos_buffer_min_change)) /
($t_acos_threshold_max_decrease - (1 + $t_acos_buffer_min_change)),
else 0 // Within buffer zone - no adjustment
);
let $adjustment_percent = case(
$within_buffer = 1 => 0%, // No change within buffer zone
// Increase adjustments for ACOS below target
$acos_ratio <= $t_acos_threshold_max_increase =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
// Decrease adjustments for ACOS above target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
-1 * ($bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change))),
else 0%
);
// Calculate target bid with CPC-based limits
let $initial_target_bid = bid * (1 + $adjustment_percent);
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_max = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No CPC data = no dynamic limit
);
let $target_bid = case(
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => $dynamic_max,
else $initial_target_bid
);
// Cooldown validation
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data across all lookback periods",
$within_buffer = 1 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Within target buffer zone",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Within target buffer zone",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Within target buffer zone",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Within target buffer zone",
else "Performance within target buffer zone"
),
$cooldown_ready = 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Recently changed - cooldown active",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Recently changed - cooldown active",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Recently changed - cooldown active",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Recently changed - cooldown active",
else "Recently changed - cooldown active"
),
$target_bid = bid => "No bid change calculated",
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => "Limited by CPC-based maximum",
$adjustment_percent > 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS below target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS below target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS below target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS below target threshold",
else "ACOS below target threshold"
),
$adjustment_percent < 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS above target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS above target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS above target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS above target threshold",
else "ACOS above target threshold"
),
else "Performance at target"
);
let $result = case(
$within_buffer = 0 and $cooldown_ready = 1 and $target_bid != bid => case(
$adjustment_percent >= $bid_max_change => "Bid Increase: Max",
$adjustment_percent >= $bid_max_change * 0.5 => "Bid Increase: Upper Range",
$adjustment_percent > 0 => "Bid Increase: Lower Range",
$adjustment_percent <= -1 * $bid_max_change => "Bid Decrease: Max",
$adjustment_percent <= -1 * $bid_max_change * 0.5 => "Bid Decrease: Upper Range",
$adjustment_percent < 0 => "Bid Decrease: Lower Range",
else "No action needed"
),
else "No action needed"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $within_buffer = 0
and $target_bid != bid
and $cooldown_ready = 1
/*
=== Core: Dynamic Bid Management ===
Purpose: Intelligent bid optimization that adjusts more aggressively when further from target ACOS, with adaptive timing controls.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable ACOS evaluation
let $bid_min_change = 3%; // CORE: Minimum bid adjustment when change is warranted
let $bid_max_change = 10%; // CORE: Maximum bid adjustment when ACOS is at or beyond target ACOS thresholds
// === Target ACOS Thresholds ===
// Between buffer and thresholds: bid adjustments scale linearly from min to max change percent
let $t_acos_buffer_min_change = 10%; // STRATEGY: No-change buffer around target ACOS - min changes start outside this zone (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]
let $t_acos_threshold_max_increase = 50%; // STRATEGY: Max increase when ACOS ≤ (Target ACOS × 50%) [e.g., 30% target = 15% max increase threshold]
let $t_acos_threshold_max_decrease = 200%; // STRATEGY: Max decrease when ACOS ≥ (Target ACOS × 200%) [e.g., 30% target = 60% max decrease threshold]
// === Time Periods ===
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $cooldown_short = 2d; // TIME: Wait period after bid change for short data periods
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $cooldown_medium = 3d; // TIME: Wait period after bid change for medium data periods
let $period_long = 0d..30d; // TIME: Tertiary evaluation period (30 days including today)
let $cooldown_long = 5d; // TIME: Wait period after bid change for long data periods
let $period_extended = 0d..60d; // TIME: Final fallback evaluation period (60 days including today)
let $cooldown_extended = 7d; // TIME: Wait period after bid change for extended data periods
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Multi-period data selection with extended coverage
let $orders_short = orders($period_short);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $orders_extended = orders($period_extended);
let $evaluation_acos = case(
$orders_short >= $orders_min => acos($period_short),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
$orders_extended >= $orders_min => acos($period_extended),
else 99999 // No reliable data
);
// Track which period was used for diagnostics
let $data_quality = case(
$orders_short >= $orders_min => "High Volume: Short Lookback",
$orders_medium >= $orders_min => "Med Volume: Medium Lookback",
$orders_long >= $orders_min => "Low Volume: Long Lookback",
$orders_extended >= $orders_min => "Very Low Volume: Extended Lookback",
else "insufficient"
);
// Adaptive cooldown periods based on data source
let $cooldown_cutoff = case(
$orders_short >= $orders_min => now() - interval($cooldown_short),
$orders_medium >= $orders_min => now() - interval($cooldown_medium),
$orders_long >= $orders_min => now() - interval($cooldown_long),
else now() - interval($cooldown_extended)
);
// Calculate performance ratio with Target ACOS validation
let $acos_ratio = case(
$evaluation_acos = 99999 => -1, // No reliable data
target acos <= 0 => -1, // Invalid target ACOS
else $evaluation_acos / target acos // Performance ratio
);
// Check if within no-change buffer zone
let $within_buffer = case(
$acos_ratio < 0 => 1, // No change if no data or invalid target
$acos_ratio >= (1 - $t_acos_buffer_min_change) and $acos_ratio <= (1 + $t_acos_buffer_min_change) => 1,
else 0
);
// Proportional scaling for bid adjustments
let $performance_gap = case(
$acos_ratio < 0 => 0, // No gap if no data
// Max increase region: ACOS at 50% of target or better
$acos_ratio <= $t_acos_threshold_max_increase => 1,
// Scaled increase region: ACOS between 50% and buffer zone (90% of target)
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
((1 - $t_acos_buffer_min_change) - $acos_ratio) /
((1 - $t_acos_buffer_min_change) - $t_acos_threshold_max_increase),
// Max decrease region: ACOS at 200% of target or worse
$acos_ratio >= $t_acos_threshold_max_decrease => 1,
// Scaled decrease region: ACOS between buffer zone (110%) and 200% of target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
($acos_ratio - (1 + $t_acos_buffer_min_change)) /
($t_acos_threshold_max_decrease - (1 + $t_acos_buffer_min_change)),
else 0 // Within buffer zone - no adjustment
);
let $adjustment_percent = case(
$within_buffer = 1 => 0%, // No change within buffer zone
// Increase adjustments for ACOS below target
$acos_ratio <= $t_acos_threshold_max_increase =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
// Decrease adjustments for ACOS above target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
-1 * ($bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change))),
else 0%
);
// Calculate target bid with CPC-based limits
let $initial_target_bid = bid * (1 + $adjustment_percent);
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_max = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No CPC data = no dynamic limit
);
let $target_bid = case(
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => $dynamic_max,
else $initial_target_bid
);
// Cooldown validation
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data across all lookback periods",
$within_buffer = 1 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Within target buffer zone",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Within target buffer zone",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Within target buffer zone",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Within target buffer zone",
else "Performance within target buffer zone"
),
$cooldown_ready = 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Recently changed - cooldown active",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Recently changed - cooldown active",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Recently changed - cooldown active",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Recently changed - cooldown active",
else "Recently changed - cooldown active"
),
$target_bid = bid => "No bid change calculated",
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => "Limited by CPC-based maximum",
$adjustment_percent > 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS below target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS below target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS below target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS below target threshold",
else "ACOS below target threshold"
),
$adjustment_percent < 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS above target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS above target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS above target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS above target threshold",
else "ACOS above target threshold"
),
else "Performance at target"
);
let $result = case(
$within_buffer = 0 and $cooldown_ready = 1 and $target_bid != bid => case(
$adjustment_percent >= $bid_max_change => "Bid Increase: Max",
$adjustment_percent >= $bid_max_change * 0.5 => "Bid Increase: Upper Range",
$adjustment_percent > 0 => "Bid Increase: Lower Range",
$adjustment_percent <= -1 * $bid_max_change => "Bid Decrease: Max",
$adjustment_percent <= -1 * $bid_max_change * 0.5 => "Bid Decrease: Upper Range",
$adjustment_percent < 0 => "Bid Decrease: Lower Range",
else "No action needed"
),
else "No action needed"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $within_buffer = 0
and $target_bid != bid
and $cooldown_ready = 1
Automatically negate zero-converting search terms to stop budget waste.
✓ Accounts with obvious search term waste - zero-order terms burning through clicks
✓ Conservative automation approach - only targets the most clear-cut waste
✓ First-time negative keyword automation - simple, safe starting point
✓ Accounts wanting budget protection without complex performance analysis
Daily Automation: Create Negative Exact Match using $action
This blueprint uses the simplest possible waste detection: zero orders + high clicks = clear waste. It evaluates each search term's lifetime performance and negates terms that have generated 20+ clicks without a single order. No complex calculations, no performance ratios - just pure waste elimination.
Conservative Targeting Philosophy: Only acts on terms with zero orders, eliminating any risk of accidentally negating valuable converting terms. This makes it ideal for first-time automation users or accounts wanting maximum safety.
Lifetime Performance Analysis: Uses complete historical data rather than recent periods, ensuring terms get adequate opportunity to convert before negation. A term needs to accumulate the full click threshold over its entire lifetime.
Binary Decision Logic: No gray areas or complex scoring - terms either qualify for negation (zero orders + sufficient clicks) or they don't. This transparency makes the automation predictable and trustworthy.
Click Threshold Selection: The 20-click default provides conservative waste removal suitable for most accounts. Increase to 30-40 clicks for accounts with higher average order values or longer consideration cycles. Decrease to 15 clicks only for very budget-conscious accounts with clear waste patterns.
Campaign Filtering Strategy: Use include/exclude filters to target specific campaign types rather than running separate blueprints. For example, set include_campaigns to ["Auto"] to focus on automatic targeting waste, or exclude_campaigns to ["Brand"] to protect brand campaigns.
Action Results: Simple "Negate" or "Keep" output makes it easy to audit automation decisions. "Negate" indicates the term met both criteria (zero orders + click threshold). "Keep" covers all other scenarios including converting terms and terms below the click threshold.
Expected Volume: In healthy accounts, expect 5-15% of search terms to qualify for negation. Higher percentages may indicate targeting issues, while very low percentages suggest the click threshold might be too conservative.
High-Waste Scenarios: Accounts with broad keyword targeting or automatic campaigns often see significant waste elimination in the first weeks of deployment. This is normal and indicates the automation is working effectively.
Low-Activity Periods: During slower seasons or after campaign restructuring, fewer terms will qualify for negation. This doesn't indicate a problem - the automation naturally adapts to activity levels.
Upgrade Considerations: This blueprint focuses only on zero-order waste. Accounts wanting to address converting but inefficient terms, or terms with poor ACOS performance, should consider the Core-level Search Term Waste Elimination blueprint for more sophisticated analysis.
/*
=== Basics: Search Term Waste Elimination ===
Purpose: Automatically negate zero-converting search terms to stop budget waste.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $base_clicks = 20; // CORE: Clicks required to negate zero-order terms (0 orders + 20 clicks = negated)
// === Campaign Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
// Simple waste removal: zero orders with sufficient clicks
let $waste_candidate = case(
$lifetime_orders = 0 and $lifetime_clicks >= $base_clicks => 1,
else 0
);
// Diagnostic properties
let $action = case(
$waste_candidate = 1 => "Negate",
else "Keep"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $waste_candidate = 1
/*
/*
=== Basics: Search Term Waste Elimination ===
Purpose: Automatically negate zero-converting search terms to stop budget waste.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $base_clicks = 20; // CORE: Clicks required to negate zero-order terms (0 orders + 20 clicks = negated)
// === Campaign Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
// Simple waste removal: zero orders with sufficient clicks
let $waste_candidate = case(
$lifetime_orders = 0 and $lifetime_clicks >= $base_clicks => 1,
else 0
);
// Diagnostic properties
let $action = case(
$waste_candidate = 1 => "Negate",
else "Keep"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $waste_candidate = 1
/*
Intelligently negate wasteful search terms using KDP performance data and relevance analysis.
✓ KDP accounts wanting sophisticated waste analysis beyond just zero-conversion terms
✓ Authors with blended profit data from both sales and page reads for reliable analysis
✓ Campaigns mixing fiction and non-fiction requiring profit-scaled efficiency thresholds
✓ Accounts needing KENP-aware optimization that considers page read engagement patterns
Daily Automation: Create Negative Exact Match using automatic detection
This blueprint uses four distinct negation paths to identify wasteful search terms in KDP campaigns. It combines profit-scaled efficiency analysis with KDP-specific blended metrics to account for both immediate sales and page read engagement. The system automatically adjusts click thresholds based on the blended profit generated, allowing higher-value terms more opportunity to convert while quickly identifying true waste.
Profit-Scaled Click Thresholds: Base threshold (20 clicks) increases by 4 clicks per dollar of blended profit generated. A term generating $5 in blended profit gets 40 total clicks before evaluation (20 + 5×4). This prevents negating terms that show profitability but need more volume to optimize.
Blended Performance Analysis: Uses KDP-specific metrics that combine sales revenue and estimated KENP royalties. This captures terms that drive page reads but not immediate sales, or vice versa, providing complete performance visibility for subscription-based reading.
Four-Path Negation Logic: Irrelevant terms (fast negation with minimal data), zero-profit waste (no engagement after sufficient testing), efficiency violations (converting but requiring too many clicks), and performance failures (converting well but poor blended ACOS).
Blended ROAS Protection: Prevents negating profitable terms by calculating target blended ROAS from target blended ACOS and protecting terms achieving 50% of that threshold. This safeguards against accidentally removing terms with acceptable profitability ratios.
Profit Scaling Strategy: The 4.0 clicks per dollar works well for mixed-genre accounts. Increase to 6.0+ for high-value non-fiction or business books where longer consideration cycles are normal. Decrease to 2.5-3.0 for quick-decision romance or thriller genres.
Target Blended ACOS Context: KDP campaigns typically target 100% blended ACOS (break-even) rather than 30% profit margins common in physical products. This reflects the different economics of digital content and subscription reading models.
Threshold Multiplier Applications: Use 1.5x for conservative accounts wanting more data before decisions, or 0.8x for aggressive waste removal in budget-constrained campaigns. This scales all thresholds proportionally while maintaining relative relationships.
Safeguard Balance: The $50 blended profit safeguard protects established performers while allowing aggressive optimization of low-value terms. Adjust based on your typical book price points and engagement patterns.
Efficiency vs Performance Negations: "Over Click Limit" indicates converting terms that require too many clicks per dollar of profit generated. "High Blended ACOS" indicates terms converting efficiently but with poor profitability ratios.
Protection Classifications: "Blended ROAS protection" means the term shows acceptable profitability even if other metrics suggest negation. "Too much blended profit" indicates established revenue streams that warrant protection regardless of efficiency.
Data Sufficiency Signals: "Insufficient clicks for profit level" means the term hasn't reached its profit-scaled threshold yet. This helps distinguish between terms needing more time versus clear non-performers.
Genre-Specific Behavior: Romance and thriller terms tend to convert quickly or fail clearly, leading to faster negation decisions. Business and self-help terms often show gradual profit accumulation, benefiting from profit-scaled thresholds.
Page Read Dynamics: Terms driving significant page reads but few sales will show in efficiency rather than zero-profit categories. The blended profit calculation captures this engagement and adjusts thresholds accordingly.
Seasonal Adaptation: During high-traffic periods (holidays, back-to-school), the profit scaling naturally accommodates increased engagement without premature negation. The system becomes more selective as terms generate more blended profit.
Volume Expectations: Expect 15-25% of search terms to qualify for negation in mature KDP campaigns, with higher percentages in the first weeks of deployment. The multi-path approach captures waste that simple zero-conversion analysis might miss.
/*
=== KDP Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using performance data and relevance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-profit terms
let $spend_threshold = 5.00; // CORE: Minimum lifetime spend required for evaluation
// === Strategy Settings ===
let $blend_profit_min_for_acos_eval = 20.00; // STRATEGY: Blended profit required for ACOS-based evaluation ($20.00 threshold)
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_blend_acos_threshold_negate = 500%; // STRATEGY: Negate if blended ACOS ≥ (Target Blended ACOS × 500%) when min clicks & profit are met [e.g., 100% target = 500% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_dollar = 4.0; // ADVANCED: Additional clicks allowed per $1.00 blended profit [e.g., $5 profit = 20 + (5 × 4) = 40 clicks]
let $threshold_multiplier = 1.0; // ADVANCED: Scales testing thresholds for clicks and spend [e.g., 1.5 = 50% higher requirements]
let $spend_scaling_enabled = 0; // ADVANCED: Scale spend requirement with profit using threshold multiplier (1=yes, 0=no) [e.g., 0 profit = $5, $5 profit = $10]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_blend_profit = 50.00; // SAFEGUARD: Never negate terms with this much blended profit or more
let $safeguard_min_blended_roas_ratio = 50%; // SAFEGUARD: Protect terms with blended ROAS ≥ (Target Blended ROAS × 50%) [e.g., 1.0 target ROAS = 0.5 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_blended_profit = blended profit(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_blended_acos = blended acos(lifetime);
let $lifetime_blended_roas = blended roas(lifetime);
// Calculate scaled click threshold based on blended profit
let $base_clicks_threshold = $clicks_threshold * $threshold_multiplier;
let $allowed_clicks = $base_clicks_threshold + ($lifetime_blended_profit * $clicks_scaling_per_dollar * $threshold_multiplier);
let $spend_required = case(
$spend_scaling_enabled = 1 => $spend_threshold + (($lifetime_blended_profit / 5.0) * $threshold_multiplier * $spend_threshold),
else $spend_threshold
);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Blended ROAS-based protection calculation
let $target_blended_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $blended_roas_protection_threshold = case(
$target_blended_roas > 0 => $target_blended_roas * $safeguard_min_blended_roas_ratio,
else 0
);
let $blended_roas_protected = case(
$lifetime_blended_profit > 0 and $target_blended_roas > 0 and $lifetime_blended_roas >= $blended_roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_profit_protection = case(
$lifetime_blended_profit >= $safeguard_blend_profit => 1,
else 0
);
let $protected_overall = case(
$high_profit_protection = 1 => 1,
$protected_term = 1 => 1,
$blended_roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-profit waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_profit_waste_candidate = case(
$lifetime_blended_profit = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_blended_acos > target acos * $t_blend_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_profit_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_profit_protection = 1 => "Protected - too much blended profit to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$blended_roas_protected = 1 => "Protected - blended ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_profit_waste_candidate = 1 => "Zero blended profit, met click threshold",
$efficiency_candidate = 1 and $lifetime_clicks >= $allowed_clicks * 1.5 => "Greatly exceeds profit-scaled click limit",
$efficiency_candidate = 1 => "Exceeds profit-scaled click limit",
$performance_candidate = 1 => "Blended ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for profit level",
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within profit-scaled click limit",
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "Blended ACOS below negation threshold",
else "Zero blended profit, needs more clicks"
);
let $result = case(
$zero_profit_waste_candidate = 1 => "Negate - Zero Profit, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_blended_profit <= 5.00 => "Negate - Low Profit, High Clicks",
$lifetime_blended_profit >= 15.00 => "Negate - Converting but Inefficient",\
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High Blended ACOS",
$high_profit_protection = 1 or $protected_term = 1 or $blended_roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
/*
=== KDP Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using performance data and relevance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-profit terms
let $spend_threshold = 5.00; // CORE: Minimum lifetime spend required for evaluation
// === Strategy Settings ===
let $blend_profit_min_for_acos_eval = 20.00; // STRATEGY: Blended profit required for ACOS-based evaluation ($20.00 threshold)
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_blend_acos_threshold_negate = 500%; // STRATEGY: Negate if blended ACOS ≥ (Target Blended ACOS × 500%) when min clicks & profit are met [e.g., 100% target = 500% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_dollar = 4.0; // ADVANCED: Additional clicks allowed per $1.00 blended profit [e.g., $5 profit = 20 + (5 × 4) = 40 clicks]
let $threshold_multiplier = 1.0; // ADVANCED: Scales testing thresholds for clicks and spend [e.g., 1.5 = 50% higher requirements]
let $spend_scaling_enabled = 0; // ADVANCED: Scale spend requirement with profit using threshold multiplier (1=yes, 0=no) [e.g., 0 profit = $5, $5 profit = $10]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_blend_profit = 50.00; // SAFEGUARD: Never negate terms with this much blended profit or more
let $safeguard_min_blended_roas_ratio = 50%; // SAFEGUARD: Protect terms with blended ROAS ≥ (Target Blended ROAS × 50%) [e.g., 1.0 target ROAS = 0.5 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_blended_profit = blended profit(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_blended_acos = blended acos(lifetime);
let $lifetime_blended_roas = blended roas(lifetime);
// Calculate scaled click threshold based on blended profit
let $base_clicks_threshold = $clicks_threshold * $threshold_multiplier;
let $allowed_clicks = $base_clicks_threshold + ($lifetime_blended_profit * $clicks_scaling_per_dollar * $threshold_multiplier);
let $spend_required = case(
$spend_scaling_enabled = 1 => $spend_threshold + (($lifetime_blended_profit / 5.0) * $threshold_multiplier * $spend_threshold),
else $spend_threshold
);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Blended ROAS-based protection calculation
let $target_blended_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $blended_roas_protection_threshold = case(
$target_blended_roas > 0 => $target_blended_roas * $safeguard_min_blended_roas_ratio,
else 0
);
let $blended_roas_protected = case(
$lifetime_blended_profit > 0 and $target_blended_roas > 0 and $lifetime_blended_roas >= $blended_roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_profit_protection = case(
$lifetime_blended_profit >= $safeguard_blend_profit => 1,
else 0
);
let $protected_overall = case(
$high_profit_protection = 1 => 1,
$protected_term = 1 => 1,
$blended_roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-profit waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_profit_waste_candidate = case(
$lifetime_blended_profit = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_blended_acos > target acos * $t_blend_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_profit_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_profit_protection = 1 => "Protected - too much blended profit to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$blended_roas_protected = 1 => "Protected - blended ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_profit_waste_candidate = 1 => "Zero blended profit, met click threshold",
$efficiency_candidate = 1 and $lifetime_clicks >= $allowed_clicks * 1.5 => "Greatly exceeds profit-scaled click limit",
$efficiency_candidate = 1 => "Exceeds profit-scaled click limit",
$performance_candidate = 1 => "Blended ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for profit level",
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within profit-scaled click limit",
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "Blended ACOS below negation threshold",
else "Zero blended profit, needs more clicks"
);
let $result = case(
$zero_profit_waste_candidate = 1 => "Negate - Zero Profit, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_blended_profit <= 5.00 => "Negate - Low Profit, High Clicks",
$lifetime_blended_profit >= 15.00 => "Negate - Converting but Inefficient",\
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High Blended ACOS",
$high_profit_protection = 1 or $protected_term = 1 or $blended_roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
Stop ad spend waste by automatically negating inefficient search terms across all campaigns.
Daily Automation: Create Negative Exact Match using built-in logic
The blueprint uses four distinct evaluation paths to identify wasteful search terms while protecting valuable converters. Zero-order terms are evaluated on click efficiency, converting terms are assessed on both efficiency and ACOS performance, with dynamic thresholds that scale based on conversion history.
/*
=== Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using efficiency targets and performance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-order terms
let $spend_threshold = 5.00; // CORE: Base spend requirement for zero-order terms
// === Strategy Settings ===
let $orders_min_for_acos_eval = 5; // STRATEGY: Orders required for ACOS-based evaluation
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_acos_threshold_negate = 400%; // STRATEGY: Negate if ACOS ≥ (Target ACOS × 400%) when min clicks & orders are met [e.g., 30% target = 120% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_order = 20; // ADVANCED: Additional clicks allowed per order [e.g., 2 orders = 20 + (2 × 20) = 60 clicks]
let $spend_scaling_per_order = 5.00; // ADVANCED: Additional spend required per order [e.g., 2 orders = $5 + (2 × $5) = $15 spend]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_orders = 10; // SAFEGUARD: Never negate terms with this many orders or more
let $safeguard_min_roas_ratio = 50%; // SAFEGUARD: Protect terms with ROAS ≥ (Target ROAS × 50%) [e.g., 3.33 target ROAS = 1.67 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_acos = acos(lifetime);
let $lifetime_roas = roas(lifetime);
// Calculate scaled thresholds based on order history
let $allowed_clicks = $clicks_threshold + ($lifetime_orders * $clicks_scaling_per_order);
let $spend_required = $spend_threshold + ($lifetime_orders * $spend_scaling_per_order);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Calculate efficiency for converting terms\
let $actual_clicks_per_order = case(
$lifetime_orders > 0 => $lifetime_clicks / $lifetime_orders,
else 999 // Treat zero-order terms as infinitely inefficient
);
// ROAS-based protection calculation
let $target_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $roas_protection_threshold = case(
$target_roas > 0 => $target_roas * $safeguard_min_roas_ratio,
else 0
);
let $roas_protected = case(
$lifetime_orders > 0 and $target_roas > 0 and $lifetime_roas >= $roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_order_protection = case(
$lifetime_orders >= $safeguard_orders => 1,
else 0
);
let $protected_overall = case(
$high_order_protection = 1 => 1,
$protected_term = 1 => 1,
$roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-order waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_order_waste_candidate = case(
$lifetime_orders = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$actual_clicks_per_order > $clicks_scaling_per_order and $sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_acos > target acos * $t_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_order_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_order_protection = 1 => "Protected - too many orders to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$roas_protected = 1 => "Protected - ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_order_waste_candidate = 1 => "Zero orders, met click threshold",
$efficiency_candidate = 1 and $actual_clicks_per_order >= $clicks_scaling_per_order * 2 => "Greatly exceeds click-per-order limit",
$efficiency_candidate = 1 => "Exceeds click-per-order limit",
$performance_candidate = 1 => "ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for order level",
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within click-per-order limit",
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "ACOS below negation threshold",
else "Zero orders, needs more clicks"
);
let $result = case(
$zero_order_waste_candidate = 1 => "Negate - Zero Orders, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_orders = 1 => "Negate - Single Order, High Clicks",
$lifetime_orders >= 2 => "Negate - Converting but Inefficient",
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High ACOS (Converting Well)",
$high_order_protection = 1 or $protected_term = 1 or $roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
/*
=== Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using efficiency targets and performance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-order terms
let $spend_threshold = 5.00; // CORE: Base spend requirement for zero-order terms
// === Strategy Settings ===
let $orders_min_for_acos_eval = 5; // STRATEGY: Orders required for ACOS-based evaluation
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_acos_threshold_negate = 400%; // STRATEGY: Negate if ACOS ≥ (Target ACOS × 400%) when min clicks & orders are met [e.g., 30% target = 120% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_order = 20; // ADVANCED: Additional clicks allowed per order [e.g., 2 orders = 20 + (2 × 20) = 60 clicks]
let $spend_scaling_per_order = 5.00; // ADVANCED: Additional spend required per order [e.g., 2 orders = $5 + (2 × $5) = $15 spend]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_orders = 10; // SAFEGUARD: Never negate terms with this many orders or more
let $safeguard_min_roas_ratio = 50%; // SAFEGUARD: Protect terms with ROAS ≥ (Target ROAS × 50%) [e.g., 3.33 target ROAS = 1.67 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_acos = acos(lifetime);
let $lifetime_roas = roas(lifetime);
// Calculate scaled thresholds based on order history
let $allowed_clicks = $clicks_threshold + ($lifetime_orders * $clicks_scaling_per_order);
let $spend_required = $spend_threshold + ($lifetime_orders * $spend_scaling_per_order);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Calculate efficiency for converting terms\
let $actual_clicks_per_order = case(
$lifetime_orders > 0 => $lifetime_clicks / $lifetime_orders,
else 999 // Treat zero-order terms as infinitely inefficient
);
// ROAS-based protection calculation
let $target_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $roas_protection_threshold = case(
$target_roas > 0 => $target_roas * $safeguard_min_roas_ratio,
else 0
);
let $roas_protected = case(
$lifetime_orders > 0 and $target_roas > 0 and $lifetime_roas >= $roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_order_protection = case(
$lifetime_orders >= $safeguard_orders => 1,
else 0
);
let $protected_overall = case(
$high_order_protection = 1 => 1,
$protected_term = 1 => 1,
$roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-order waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_order_waste_candidate = case(
$lifetime_orders = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$actual_clicks_per_order > $clicks_scaling_per_order and $sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_acos > target acos * $t_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_order_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_order_protection = 1 => "Protected - too many orders to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$roas_protected = 1 => "Protected - ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_order_waste_candidate = 1 => "Zero orders, met click threshold",
$efficiency_candidate = 1 and $actual_clicks_per_order >= $clicks_scaling_per_order * 2 => "Greatly exceeds click-per-order limit",
$efficiency_candidate = 1 => "Exceeds click-per-order limit",
$performance_candidate = 1 => "ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for order level",
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within click-per-order limit",
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "ACOS below negation threshold",
else "Zero orders, needs more clicks"
);
let $result = case(
$zero_order_waste_candidate = 1 => "Negate - Zero Orders, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_orders = 1 => "Negate - Single Order, High Clicks",
$lifetime_orders >= 2 => "Negate - Converting but Inefficient",
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High ACOS (Converting Well)",
$high_order_protection = 1 or $protected_term = 1 or $roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
© Merch Jar LLC