Features
Recipes V2 is Merch Jar’s most powerful system yet for creating automated rules for Amazon Ads. It introduces more flexible, intuitive ways to build recipes — including advanced time periods, math operations, variables, conditional logic, and improved readability.
If you're familiar with V1, the core concepts will feel similar, but V2 adds major new capabilities to help automate even more complex strategies.
case
(if/else) statements.and
/ or
, plus built-in operator precedence.Recipes V2 separates metrics and properties to make writing rules more intuitive.
clicks(30d) > 10 // Clicks is a metric and requires a date range
bid < $1.00 // Bid is a property and does not use a date range
Here's a quick reference:
See the full list of available metrics and properties.
Every metric must include a time period to define when the data is pulled from. Recipes V2 supports three ways to define time periods:
Look back a set number of days from today. Useful for recent performance.
clicks(30d)
More examples:
clicks(7d)
sales(90d)
spend(14d)
Use exact calendar dates for precise periods. Format: YYYY-MM-DD..YYYY-MM-DD
sales(2024-01-01..2024-01-31)
Compare past periods relative to today.
(X..Y)
From X days ago to Y days ago(..X)
From today until X days ago(X..)
From X days ago to all earlier data(..)
or (lifetime)
From today to all earlier data; lifetime available dataExamples:
clicks(30d..60d) // From 30 to 60 days ago
clicks(..60d) // From today until 60 days ago
clicks(30d..) // From 30 days ago to all time
clicks(..) // All available data
clicks(lifetime) // Same as above
Recipes V2 lets you compare metrics against each other and compare different time periods.
Supported operators: >
, >=
, <
, <=
, =
, !=
Example:
orders(1d..30d) < orders(31d..60d)
You can perform math on metrics and numeric properties to create more flexible conditions.
Supported operators: +
, -
, *
, /
Examples:
bid < cpc(30d) + 0.05
sales(30d) < sales(90d) / 3 * 0.9
Order of operations applies: multiplication and division are evaluated before addition and subtraction.
bid * 2 + 0.05 < 10
bid * (2 + 0.05) < 10
Variables let you store a value or calculation and reuse it throughout your recipe. Think of them as saved expressions to simplify complex logic.
let
to declare.case
(if/else) statements// Average monthly sales over last 90 days
let avg_sales = sales(90d) / 3;
clicks(30d) < avg_sales * 0.9
// Find items where sales dropped more than 20% compared to last period
let change_in_sales = sales(30d) / sales(31d..61d);
let drop_threshold = 20%;
change_in_sales < (1 - drop_threshold / 100)
let time = 60d;
acos(time) > 30% and clicks(time) > 100
let avg_sales = sales(90d) / 3;
let threshold = avg_sales * 0.9;
sales(30d) < threshold
The case
function lets you build conditional logic, similar to if/else statements in programming. You can assign different values based on conditions.
let variable_name = case(
when condition1 then value1,
when condition2 then value2,
else default_value
);
when...then
conditions.else
fallback.let volume = case(
when orders(30d) > 20 then "high",
when orders(30d) > 10 then "medium",
else "low"
);
(volume = "high" and acos(30d) > 50%) or (volume = "medium" and acos(30d) > 40%)
Combine multiple conditions using and
and or
.
Examples:
clicks(30d) > 10 and sales(30d) = 0
spend(30d) > 1000 or orders(30d) = 0
Recipes V2 allows mixing and
and or
in the same expression — but and is always evaluated before or, unless parentheses are used.
Example:
clicks(30d) > 10 and impressions(30d) > 100 or sales(30d) = 0
is treated as:
(clicks(30d) > 10 and impressions(30d) > 100) or sales(30d) = 0
To override this:
clicks(30d) > 10 and (impressions(30d) > 100 or sales(30d) = 0)
Tip: Use parentheses if unsure how a complex condition will be evaluated.
Use comments to explain parts of your recipe.
// This is a comment
/*
This is a multi-line comment
Spanning multiple lines
*/
Properties like campaign name
or ad group name
support string comparisons.
Available operators:
!=
contains
does not contain
starts with
ends with
Examples:
campaign name contains "lottery"
ad group name starts with "B00K"
campaign name does not contain "test"
sales(30d) < sales(31d..61d) * 0.9
let days = 365d;
let drop_threshold = 80%;
let avg_sales = sales(days) / 30;
sales(30d) < avg_sales * drop_threshold and clicks(30d) > 10
// Set target ACoS based on AOV (Average Order Value)
let time = 30d;
let target_acos = case(
when aov(time) < $20 then 20%,
when aov(time) < $30 then 25%,
when aov(time) < $50 then 30%,
else 40%
);
// Find targets where ACoS exceeds their target based on AOV
acos(time) > target_acos
// User set variables
let target_acos = 30%;
let range = 30d;
let cpc_threshold = 20%;
// Calculate Target CPC
let target_cpc = sales(range) / clicks(range) * target_acos
// Find keywords above Target CPC Threshold
cpc(range) > target_cpc * (1 + cpc_ threshold)
// Detect rising CPC trend over last 30 days vs. prior 30 days
let cpc_trend = cpc(30d) / cpc(31d..61d);
// If CPC is up 20% or more, reduce bid
cpc_trend > 1.2
// Campaign started within last 60 days and starting to get sales
campaign start date > 60 days ago
and sales(30d) > 5
and acos(30d) < 40%
// V1 Syntax
over the last 30 days clicks > 10
// V2 Syntax
clicks(30d) > 10
// V1 Syntax
over the last 30 days clicks > 10 and acos > 50%
// V2 Syntax
clicks(30d) > 10 and acos(30d) > 50%
// V1 Syntax
over the lifetime sales > 100
// V2 Syntax
sales(lifetime) > 100
sales(..) > 100