Features
Version 1.0 — Last Updated: April 2026
Standards and patterns for creating Merch Jar automation segments. Use alongside the V2 Logic Syntax Reference for syntax validation.
Target audience: Established Amazon advertisers — brands, aggregators, and agencies managing significant ad spend. Segments should assume users care about both control and scale, and are willing to trade simplicity for robust, reliable logic.
Handle multiple scenarios in one segment when possible:
Change Bid: Set ($) using $target_bid where $target_bid is calculatedChange Bid: Increase (%) using $percentage_change with positive/negative valuesThis provides cleaner logic, more precise control, and easier debugging.
Every segment must include a header comment:
/*
=== [Collection]: [Segment Name] ===
Version: [X.X]
Docs: merchjar.com/templates?t=[slug]
Purpose: [One sentence description - max 20 words]
Dataset: [Dataset name]
Recommended: [Action Type] | [Schedule]
*/Slug generation: Lowercase name with hyphens for spaces, colons removed.
seasonal-bid-tunerkdp-core-product-ad-waste-eliminationVersioning: Minor (1.1) for new features, path changes, setting additions. Major (2.0) for breaking changes or fundamental rewrites. Version must match the header, CMS Version field, and Logs tab entries.
Default: Keywords & Targets — covers both manual keywords and product/auto targets. Use for all bid management segments unless there's a specific reason not to.
[metric]_[purpose]_[context]_[qualifier]
Pattern: t_acos_[purpose]_[context]_[qualifier]
let $t_acos_threshold_increase = 80%; // STRATEGY: Increase bids when ACOS <= (Target ACOS × 80%) [e.g., 30% target = 24% threshold]
let $t_acos_buffer = 10%; // CORE: No-change buffer around target ACOS (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]
let $t_acos_threshold_pause = 300%; // STRATEGY: Pause when ACOS >= (Target ACOS × 300%) [e.g., 30% target = 90% threshold]Data reliability:
let $orders_min = 2; // CORE: Minimum orders needed for reliable ACOS data
let $orders_min_for_acos = 5; // ADVANCED: Orders required for advanced ACOS evaluation
let $clicks_min = 20; // CORE: Minimum clicks required for evaluation
let $spend_min = 5.00; // CORE: Minimum lifetime spend threshold ($5.00 threshold)Bid adjustments:
let $bid_min_change = 3%; // STRATEGY: Minimum bid change when adjustment is warranted
let $bid_max_change = 10%; // STRATEGY: Maximum bid change regardless of performance gapTime controls:
let $cooldown_period = 2d; // TIME: Wait 2 days after bid change before adjusting again
let $cooldown_recent = 1d; // TIME: Short cooldown for high-confidence scenarios
let $cooldown_extended = 7d; // TIME: Extended cooldown for volatile keywordsCPC-based limits:
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 limitsUse role-based names. Only define periods actually used in the logic.
Two periods:
let $period_recent = 0d..7d; // TIME: Recent evaluation period
let $period_baseline = 0d..30d; // TIME: Baseline comparison periodThree or more periods:
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $period_long = 0d..30d; // TIME: Extended evaluation period (30 days including today)
let $period_extended = 0d..60d; // TIME: Maximum evaluation period (60 days including today)Safety and control variables use purpose-first naming for visual prominence:
let $safeguard_orders = 10; // SAFEGUARD: Never pause keywords with 10+ lifetime orders
let $protected_terms = ["brand"]; // SAFEGUARD: Never negate search terms containing these keywords
let $excluded_campaigns = ["test"]; // FILTER: Exclude campaigns containing these terms
let $cooldown_period = 2d; // TIME: Wait 2 days after last bid changePurpose-first exceptions: safeguard_*, protected_*, excluded_*, cooldown_*, *_limit_*
[""] — matches all (empty string behavior)["NEVER_MATCH"] — excludes nothing["NEVER_MATCH"] — protects nothingCORE — Essential settings most users need to understandSTRATEGY — Segment-specific logic and behaviorTIME — Period definitions and timing controlsADVANCED — Sophisticated features for power usersFILTER — Segment targeting and exclusionsSAFEGUARD — Protection and safety controlsAlign inline comments where possible. Add blank lines between setting groups.
Target ACOS variables — always include formula and example:
let $t_acos_threshold_increase = 80%; // STRATEGY: Increase bids when ACOS <= (Target ACOS × 80%) [e.g., 30% target = 24% threshold]Buffer variables — always include ± calculation and range:
let $t_acos_buffer = 10%; // CORE: No-change buffer around target ACOS (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]Multiplier variables — always include calculation and concrete example:
let $cpc_multiplier = 2.0; // ADVANCED: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]Array variables — show usage examples and clarify behavior:
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]// === Core Settings === (always first)
// === Strategy Settings === (segment-specific logic)
// === Time Periods === (when relevant)
// === Advanced Settings === (power user controls)
// === Safeguards === (when needed)
// === Segment Filters === (always last)Group safety variables prominently. Order from basic to advanced.
Use these patterns in all segments.
let $orders_recent = orders($period_recent);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $evaluation_acos = case(
$orders_recent >= $orders_min => acos($period_recent),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
else 99999 // Sentinel value for no reliable data
);let $acos_ratio = case(
$evaluation_acos = 99999 => -1, // No reliable data
target acos <= 0 => -1, // Invalid target
else $evaluation_acos / target acos // Performance ratio
);
let $acos_acceptable_for_increase = case(
target acos <= 0 => 0, // Invalid target
$evaluation_acos = 99999 => 0, // No data
$evaluation_acos <= target acos * $t_acos_threshold_increase => 1,
else 0
);let $cooldown_ready = case(
is_null(last bid change) => 1, // Never changed
last bid change < now() - interval($cooldown_period) => 1, // Grace period passed
else 0 // Recently changed
);let $include_campaigns = [""]; // Matches all campaigns
let $exclude_campaigns = ["NEVER_MATCH"]; // Excludes nothing
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)state = "effectively enabled"
// Note: Search Terms dataset has no state property — skip this filterlet $avg_cpc = cpc($period_long);
let $dynamic_max_bid = case(
$avg_cpc > 0 => $avg_cpc * $cpc_multiplier,
else 999 // No limit if no CPC data
);
let $target_bid = case(
$calculated_bid > $dynamic_max_bid => $dynamic_max_bid,
else $calculated_bid
);Use when adding sophistication.
let $adaptive_cooldown = case(
orders($period_recent) >= $orders_min => $cooldown_period,
orders($period_medium) >= $orders_min => $cooldown_period * 1.5,
orders($period_long) >= $orders_min => $cooldown_period * 2,
else $cooldown_period * 3
);
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < now() - interval($adaptive_cooldown) => 1,
else 0
);let $data_confidence = case(
orders($period_recent) >= $orders_min => 1.0,
orders($period_medium) >= $orders_min => 0.8,
orders($period_long) >= $orders_min => 0.6,
else 0.3
);Use sparingly, when justified by segment complexity.
let $volume_score = case(
clicks($period_recent) >= 50 => 1.0,
clicks($period_recent) >= 20 => 0.8,
clicks($period_recent) >= 10 => 0.6,
else 0.3
);
let $composite_score = ($volume_score * 0.6) + ($recency_score * 0.4);let $recent_acos = case(orders(0d..7d) >= 1 => acos(0d..7d), else 99999);
let $previous_acos = case(orders(8d..14d) >= 1 => acos(8d..14d), else 99999);
let $momentum_signal = case(
$recent_acos = 99999 or $previous_acos = 99999 => "insufficient_data",
$recent_acos < $previous_acos * 0.8 => "improving",
$recent_acos > $previous_acos * 1.2 => "declining",
else "stable"
);Prefer Target ACOS adjustments over campaign filtering when: different campaign types need different thresholds, different match types require different aggressiveness, product categories have varying margins, or account-wide strategy is changing.
Use campaign filtering instead for: testing campaigns, paused campaign workflows, temporary exclusions.
Adjust Target ACOS in Ad Manager for different campaign types rather than excluding campaigns. Target ACOS can be set at the account, campaign, ad group, or individual target level and will cascade down.
acos over roi or roas — primary efficiency metricorders over clicks for reliability checkstarget acos over hard-coded percentagesstate = "effectively enabled" over state = "enabled" where availableKDP segments use:
blended acos instead of acos (100% benchmark vs 30% standard)blended profit instead of orders for reliability checks (3 blended profit ≈ 1 order)blended profit instead of sales for revenue calculationsKDP variable naming:
let $blend_profit_min = 6.00; // CORE: Minimum blended profit for reliable ACOS evaluation ($6.00 threshold)
let $t_blend_acos_threshold_increase = 80%; // STRATEGY: Increase bids when blended ACOS <= (Target Blended ACOS × 80%)Every segment must have exactly two diagnostic properties: $reason and $result.
For single action type with meaningful magnitude ranges — bid management, budget adjustment:
let $result = case(
$action_needed = 1 => case(
$change_percent >= $max_change => "Bid Increase: Maximum",
$change_percent >= $max_change * 0.5 => "Bid Increase: Upper Range",
$change_percent > 0 => "Bid Increase: Lower Range",
$change_percent <= -1 * $max_change => "Bid Decrease: Maximum",
$change_percent <= -1 * $max_change * 0.5 => "Bid Decrease: Upper Range",
else "Bid Decrease: Lower Range"
),
else "No Action"
);For multiple blocking conditions or complex qualification logic:
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data for reliable ACOS",
$cooldown_ready = 0 => "Recently changed - in cooldown period",
$acos_ratio <= $t_acos_threshold_increase => "ACOS below increase threshold",
$protected_term = 1 => "Protected by safeguard rules",
else "ACOS above target but within acceptable range"
);
let $result = case(
$action_needed = 1 => "Bid Adjustment Applied",
else "No Action"
);For segments that assess rather than act:
let $reason = case(
$acos_trend = "improving" => "ACOS improving over evaluation period",
$acos_trend = "declining" => "ACOS worsening over evaluation period",
$impression_volatility = 1 => "High impression volatility detected",
else "Stable ACOS performance maintained"
);
let $result = case(
$confidence_score >= 0.8 => "High Confidence Assessment",
$confidence_score >= 0.5 => "Moderate Confidence Assessment",
$data_sufficiency = 0 => "Insufficient Data",
else "Low Confidence Assessment"
);$reason — standalone performance assessment:
$result — action with magnitude:
Before finalizing, trace all logic paths:
/*
=== [Segment Name] ===
Version: 1.0
Docs: merchjar.com/templates?t=[slug]
Purpose: [One sentence - max 20 words]
Dataset: [Dataset Type]
Recommended: [Action Type]: [Method] using [Variable] | [Schedule]
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders needed for reliable ACOS data
// === Strategy Settings ===
let $t_acos_threshold_increase = 80%; // STRATEGY: Increase bids when ACOS <= (Target ACOS × 80%) [e.g., 30% target = 24% threshold]
let $bid_min_change = 3%; // STRATEGY: Minimum bid change when adjustment is warranted
let $bid_max_change = 10%; // STRATEGY: Maximum bid change regardless of performance gap
// === Time Periods ===
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $period_long = 0d..30d; // TIME: Extended evaluation period (30 days including today)
let $cooldown_period = 2d; // TIME: Wait 2 days after bid change before adjusting again
// === Advanced Settings ===
let $cpc_multiplier = 2.0; // ADVANCED: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
// === 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
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
let $orders_recent = orders($period_short);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $evaluation_acos = case(
$orders_recent >= $orders_min => acos($period_short),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
else 99999
);
let $acos_ratio = case(
$evaluation_acos = 99999 => -1,
target acos <= 0 => -1,
else $evaluation_acos / target acos
);
let $qualifies_for_increase = case(
target acos <= 0 => 0,
$evaluation_acos = 99999 => 0,
$evaluation_acos <= target acos * $t_acos_threshold_increase => 1,
else 0
);
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < now() - interval($cooldown_period) => 1,
else 0
);
let $avg_cpc = cpc($period_long);
let $calculated_bid = bid * (1 + $bid_change_percent);
let $dynamic_max_bid = case(
$avg_cpc > 0 => $avg_cpc * $cpc_multiplier,
else 999
);
let $target_bid = case(
$calculated_bid > $dynamic_max_bid => $dynamic_max_bid,
else $calculated_bid
);
let $action_needed = case(
$qualifies_for_increase = 1 and $cooldown_ready = 1 and $target_bid > bid => 1,
else 0
);
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data for reliable ACOS",
$qualifies_for_increase = 0 and $acos_ratio > 0 => "ACOS above increase threshold",
$cooldown_ready = 0 => "Recently changed - cooling down",
$target_bid = bid => "No bid change calculated",
$calculated_bid > $dynamic_max_bid => "Limited by CPC-based maximum",
$qualifies_for_increase = 1 => "ACOS below target threshold",
else "Performance at target"
);
let $result = case(
$action_needed = 1 => case(
$bid_change_percent >= $bid_max_change => "Bid Increase: Maximum",
$bid_change_percent >= $bid_max_change * 0.5 => "Bid Increase: Upper Range",
$bid_change_percent > 0 => "Bid Increase: Lower Range",
else "No Action"
),
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 $action_needed = 1Essential (all segments):
[""] and ["NEVER_MATCH"])is_null() pattern$reason and $resultRecommended:
Override standards when segment-specific context makes a different approach better for users. Always maintain: Target ACOS integration over hard-coded thresholds, safe array defaults and state filtering, two diagnostic properties, essential code patterns for data reliability, and version number in header.
Document deviations with comments explaining the segment-specific reasoning.
© Merch Jar LLC