Offers
An offer is an individual earning opportunity within a program. While the program defines the overall container — time frame, supplier, program-level qualifications — each offer specifies what is incentivized, how the incentive is calculated, and any additional conditions that must be met for the offer to pay out.
A program typically contains one or more offers. For example, a crop protection program might include a base rebate offer, a growth bonus offer, and a loyalty bonus offer — each targeting different SKUs, using different strategies, and having their own qualification requirements.
At a Glance
| Component | Purpose |
|---|---|
| Identification | Unique key and label |
| SKU Keys | Which products are incentivized by the offer |
| Time Periods | Named date ranges scoping when the offer is active |
| Transaction Types | Which transaction flows the offer covers |
| Strategy & Calculator | How the incentive is structured and what formula is used |
| Qualifications & Qualifier | Offer-level conditions that gate payout |
| Attributes | Arbitrary metadata labels |
Identification
| Field | Type | Description |
|---|---|---|
key |
string |
Unique identifier for the offer. Convention: {program_key}.{offer_name} (e.g., corteva.2026.retailer.national.crop_protection.base) |
label |
string |
Human-readable name displayed in UIs |
Programs Response
SKU Keys
The sku_keys array lists every SKU that the offer incentivizes. These are the products whose transactions will produce potential earnings when the offer is evaluated.
{
"sku_keys": [
"agri_shield_insecticide_2.5_gal_53551",
"crop_guard_30_l_herbicide_2.5_gal_22654"
]
}
Note
Offer-level sku_keys are the SKUs that earn the incentive. These may differ from the SKUs in qualification filters or stepped threshold definitions, which can reference entirely different products.
Time Periods
Offers can define their own time periods in addition to the program-level periods. These follow the same structure as program time periods:
| Field | Type | Description |
|---|---|---|
key |
string |
Unique identifier referenced by incentives and qualifications |
label |
string |
Human-readable name |
start_date |
string |
Period start date (ISO 8601) |
start_date_label |
string \| null |
Human-friendly start date label |
end_date |
string |
Period end date (ISO 8601) |
end_date_label |
string \| null |
Human-friendly end date label |
Programs Response
{
"time_periods": [
{
"key": "incentive_period",
"label": "Full Season",
"start_date": "2025-09-01",
"end_date": "2026-08-31"
}
]
}
Offer time periods are merged with program-level time periods. If an offer references a period_key that exists at both levels, the offer's definition takes precedence.
Transaction Types
The transaction_types array lists which transaction flows the offer covers. These are extracted from the offer's incentive structure.
| Transaction Type | Description |
|---|---|
retailer_purchases_from_distribution |
Purchases a retailer makes from a distributor |
retailer_sales_to_growers |
Sales a retailer makes to end-user growers |
contractor_purchases_from_distribution |
Purchases a contractor makes from distribution |
distributor_sales_to_retail |
Sales a distributor makes to retailers |
inventory |
Inventory-related transactions |
Strategy & Calculator
Every offer has two fields that together define how incentives are structured and computed:
| Field | Type | Description |
|---|---|---|
strategy_key |
string |
How the incentive is structured: "standard", "stepped", or "stacked" |
calculator_key |
string |
The formula used to compute the incentive amount |
Strategy Key
The strategy determines the shape of the incentive data and how rates are resolved:
| Strategy | Incentive Shape | Rate Determined By |
|---|---|---|
standard |
incentives: [...] (array) |
Fixed per-SKU rate |
stepped |
incentive: {} (object) |
Threshold-based tier — highest qualifying tier applies |
stacked |
incentive: {} (object) |
Coverage-unit overlap across SKU sets |
For a complete reference of how each strategy works, including detailed examples, see Strategies.
Calculator Key
The calculator determines the formula applied to compute the incentive amount:
calculator_key |
What It Means |
|---|---|
percent_of_amount |
Incentive is a percentage of the transaction's dollar amount. A rate of 5.0 means 5% |
dollars_per_unit |
Incentive is a flat dollar amount per unit of quantity purchased |
fixed_amount |
Incentive is a fixed dollar total for the offer, distributed proportionally across qualifying transactions |
dollars_per_coverage_unit |
Incentive is a flat dollar amount per coverage unit (e.g., per acre). Used exclusively with the stacked strategy |
Valid Strategy + Calculator Combinations
Not all combinations are valid:
| Strategy | Valid Calculators |
|---|---|
standard |
percent_of_amount, dollars_per_unit, fixed_amount |
stepped |
percent_of_amount, dollars_per_unit, fixed_amount |
stacked |
dollars_per_coverage_unit |
Incentive Structure
The incentive structure varies by strategy and is flattened directly into the offer object. The strategy_key tells you which shape to expect.
Standard Incentives
Standard offers use an incentives array. Each entry defines rates for a specific period and transaction type:
{
"strategy_key": "standard",
"calculator_key": "percent_of_amount",
"incentives": [
{
"key": "incentive_period_retailer_purchases_from_distribution",
"label": "Full Season Incentive",
"period_key": "incentive_period",
"transaction_type": "retailer_purchases_from_distribution",
"rates": [
{
"sku_key": "agri_shield_insecticide_2.5_gal_53551",
"rate": 3.0,
"measure": "percent"
}
]
}
]
}
Reading this: Every qualifying transaction for agri_shield_insecticide_2.5_gal_53551 during the incentive_period earns a 3% incentive on the dollar amount. See Standard strategy for full details.
Stepped Incentive
Stepped offers use a single incentive object with filters, a threshold_definition, and tiered rates:
{
"strategy_key": "stepped",
"calculator_key": "percent_of_amount",
"incentive": {
"filters": [
{
"period_key": "incentive_period",
"sku_keys": ["agri_shield_insecticide_2.5_gal_53551", "agri_shield_insecticide_bulk_63374"],
"transaction_type": "retailer_purchases_from_distribution"
}
],
"threshold_definition": {
"type": "aggregated_amount",
"filters": [
{
"period_key": "incentive_period",
"sku_keys": ["crop_guard_30_l_herbicide_2.5_gal_22654", "field_hammer_fungicide_1_gal_61492"],
"transaction_type": "retailer_purchases_from_distribution"
}
]
},
"rates": [
{ "key": "tier_2", "threshold": 2000.0, "rate": 15.0, "measure": "percent" },
{ "key": "tier_1", "threshold": 1000.0, "rate": 10.0, "measure": "percent" }
]
}
}
Reading this: The rate is determined by how much of crop_guard_30_l_herbicide_2.5_gal_22654/field_hammer_fungicide_1_gal_61492 is purchased (the threshold), but the incentive is earned on agri_shield_insecticide_2.5_gal_53551/agri_shield_insecticide_bulk_63374 transactions. See Stepped strategy for full details.
Stacked Incentive
Stacked offers use a single incentive object with sku_sets and stacks:
{
"strategy_key": "stacked",
"calculator_key": "dollars_per_coverage_unit",
"incentive": {
"sku_sets": [
{
"key": "seed",
"period_key": "incentive_period",
"transaction_type": "retailer_sales_to_growers",
"conversion": {
"coverage_unit": "acre",
"rates": [{ "sku_key": "agri_shield_insecticide_bulk_63374", "rate": 1.0, "from": "unit" }]
},
"rates": [{ "sku_key": "agri_shield_insecticide_bulk_63374", "rate": 0.0, "measure": "dollars" }]
},
{
"key": "seed_treatment",
"period_key": "incentive_period",
"transaction_type": "retailer_sales_to_growers",
"conversion": {
"coverage_unit": "acre",
"rates": [{ "sku_key": "field_hammer_fungicide_bulk_52112", "rate": 0.00921875, "from": "gal" }]
},
"rates": [{ "sku_key": "field_hammer_fungicide_bulk_52112", "rate": 0.75, "measure": "dollars" }]
}
],
"stacks": [
{ "key": "seed_and_seed_treatment", "sku_set_keys": ["seed", "seed_treatment"] }
]
}
}
Reading this: The incentive pays $0.75 per acre where both seed and seed treatment are purchased together. See Stacked strategy for full details.
Qualifications & Qualifier
Offers can define their own qualifications in addition to program-level qualifications. Offer-level qualifications gate whether that specific offer pays out, independent of other offers in the same program.
| Field | Type | Description |
|---|---|---|
qualifications |
[Qualification] |
Array of qualification definitions. See Qualifications for all seven types |
qualifier |
string \| null |
Boolean expression combining qualification keys with AND / OR logic. If null, the offer is always considered qualified (assuming the program-level qualifier passes) |
Evaluation Order
- Program-level qualifications are evaluated first
- If the program's qualifier evaluates to
false, all offers in the program are skipped - If the program qualifies, each offer's offer-level qualifications are evaluated independently
- Only offers whose qualifier evaluates to
true(or isnull) produce potential earnings
Programs Response
{
"key": "corteva.2026.retailer.national.crop_protection.growth",
"label": "Growth Bonus",
"qualifications": [
{
"type": "yoy_amount_index",
"key": "yoy_growth",
"label": "Year-over-Year Growth",
"operator": "greater_than_or_equal_to",
"value": 105.0,
"numerator": {
"filters": [
{
"period_key": "incentive_period",
"sku_keys": ["agri_shield_insecticide_2.5_gal_53551"],
"transaction_type": "retailer_purchases_from_distribution"
}
]
},
"denominator": {
"filters": [
{
"period_key": "prior_year_period",
"sku_keys": ["agri_shield_insecticide_2.5_gal_53551"],
"transaction_type": "retailer_purchases_from_distribution"
}
]
},
"attributes": []
}
],
"qualifier": "yoy_growth"
}
Reading this: This growth bonus offer requires the participant to grow their purchases by at least 5% year-over-year. The program-level qualifications must also be met before this offer-level qualification is evaluated. For details on how each qualification type works, see Qualifications.
Attributes
Attributes are arbitrary metadata labels attached to an offer. They are not used in calculation logic.
| Field | Type | Description |
|---|---|---|
type |
string |
Category or type of the attribute |
value |
string |
The attribute value |
label |
string |
Human-readable label |
Complete Offer Response
Putting all the components together, a full offer within the GET /programs response looks like this:
{
"key": "corteva.2026.retailer.national.crop_protection.base",
"label": "Base Rebate",
"attributes": [
{ "type": "tier", "value": "base", "label": "Base Rebate" }
],
"sku_keys": [
"agri_shield_insecticide_2.5_gal_53551",
"crop_guard_30_l_herbicide_2.5_gal_22654"
],
"time_periods": [
{
"key": "incentive_period",
"label": "Full Season",
"start_date": "2025-09-01",
"end_date": "2026-08-31"
}
],
"transaction_types": ["retailer_purchases_from_distribution"],
"calculator_key": "percent_of_amount",
"strategy_key": "standard",
"incentives": [
{
"key": "incentive_period_retailer_purchases_from_distribution",
"label": "Full Season Incentive",
"period_key": "incentive_period",
"transaction_type": "retailer_purchases_from_distribution",
"rates": [
{ "sku_key": "agri_shield_insecticide_2.5_gal_53551", "rate": 3.0, "measure": "percent" },
{ "sku_key": "crop_guard_30_l_herbicide_2.5_gal_22654", "rate": 3.0, "measure": "percent" }
]
}
],
"qualifications": [],
"qualifier": null
}
Summary
- An offer is an individual earning opportunity nested within a program
- Each offer specifies which SKUs earn, how the incentive is calculated (strategy + calculator), and any offer-level qualifications
- The strategy determines the incentive structure — see Strategies for
standard,stepped, andstacked - The calculator determines the formula:
percent_of_amount,dollars_per_unit,fixed_amount, ordollars_per_coverage_unit - Offer-level qualifications are evaluated only after the program-level qualifier passes — see Qualifications
- A program can contain multiple offers, each with different strategies, rates, and qualification requirements