Skip to content

Changelog

All notable changes to the API will be documented here.

2026-03-26

Added

A new qualification of type brand_count has been added. This supports qualifications that require the transactions to have a specific count of unique brands.

GET /programs

This qualification will have a unique structure that explicitly states the brands involved in this qualification and if any sku_keys were excluded from the qualification. The filters indicate the various attributes that the transactions will be filtered on, this is the same pattern as used by other qualification filters.

{
    "type": "brand_count",
    "key": "purchase_minimum_brand_count_qualification",
    "label": "Purchase at least 3 FMC brands",
    "operator": "greater_than_or_equal_to",
    "value": 3,
    "filters": [
        {
            "period_key": "current_season",
            "sku_keys": [
                "adastrio_fungicide_120_gal_99900002",
                "adastrio_fungicide_2.5_gal_99900001",
                                ...
            ],
            "transaction_type": "retailer_sales_to_growers"
        }
    ],
    "brand_keys": [
        "adastrio_fungicide",
        "anthem_maxx_herbicide"
                        ...
    ],
    "excluded_sku_keys": [],
    "attributes": []
}
  ```

There are no changes to any other endpoints from this feature addition.

## 2026-03-24

### Added

The concept of rolling transactions up to a specific attribute of the transaction for calculations has been added, it will be called `group_by`. The configuration will add this attribute when applicable to a program and it will be associated with a `transaction_type`.
For Example: When a program needs all its sales to growers to be grouped by the grower's id, the configuration will use `group_by` for it.

### `GET /programs`
{ "key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000", "label": "2025 - 2026 Basf → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000", "attributes": [], "time_frame": "2026", ... "group_by": [ { "transaction_type": "retailer_sales_to_growers", "field": "purchaser", "key": "id", "type": "string" } ], "verifications": [], "offers": [...] }
This `group_by` indicates that all transactions of type `retailer_sales_to_growers` for `basf` for `2026` will need a `purchaser.id` in order to calculate. Even though only one program may use this grouping, if the engine encounters a `retailer_sales_to_growers` transaction with a sku that is relevant to this program but does not have the `purchaser.id` data, the request will error with:
{ "data": [], "errors": [ { "status": "400", "title": "Bad Request", "detail": "incomplete 'group_by' info: transactions of type 'retailer_sales_to_growers' are missing 'purchaser.id': [01JAD80XDZWGFZDN8WWJJHVDFQ]" } ], "meta": { "api_version": "v1" } }
There are no changes to the `POST /calculations` output.

## 2026-03-02

### Added

### `POST /calculations`
Some programs targeting grower sales (`retailer_sales_to_growers`) require that transactions to be grouped by grower. In order to achieve that, the incoming requests to `POST /calculations` endpoint needs to accommodate purchaser(grower) data which will be done via an additional attribute:
```json
          "purchaser": {
            "id": "895788"
          }
Including the purchaser.id is very similar to the inclusion of seller.key. All retailer_sales_to_growers transactions should have the purchaser object populated with the grower's id for accurate calculations. The calculation engine will determine when a program/offer needs to use the purchaser.id as directed by the configuration. There is no downside to adding the purchaser.id on all retailer_sales_to_growers transactions.

{
  "participant_key": "ag_vend_austin_tx_000",
  "entities": [
    {
      "id": "350FEN",
      "properties": [],
      "transactions": [
        {
          "transaction_id": "01JAD80XDZM296AGN3T33ZWMJF",
          "transaction_type": "retailer_sales_to_growers",
          "invoice_date": "2022-09-16",
          "sku_key": "agri_shield_insecticide_2.5_gal_53551",
          "quantity": 2007.0,
          "uom_key": "gal",
          "amount": 10254,
          "purchaser": {
            "id": "895788"
          },
          "properties": []
        }
      ]
    }
  ],
  "relationships": [],
  "properties": []
}

2026-02-25

Added

A new strategy named stacked has been added. Programs configured with this strategy will have strategy_key = stacked.

GET /programs

This endpoint will output offers with stacked strategy with a new structure for incentive like shown below. Unlike standard strategy, stacked does not support incentives: [...], instead it has an object incentive: {} The incentive object has two high level keys: sku_sets[]: This defines all sets of skus used by the sku_set_keys in stacks. This has all details about the period_key, transaction_type and the acre conversion rate for the sku as well as the pay rate of the sku. stacks[]: This has a key and sku_set_keys. The key for the stack that is used for the calculation is returned as incentive_rate_key in the potential_earnings

{
  "data": [
    {
      "key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000",
      "label": "2025 - 2026 Basf → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000",
      "summary": "The BASF Seed Treatment Soybean Pair Up Program provides full season incentive support for purchasing BASF participating brands.",
      "description": "Earn varying percent incentives once you attain 75% of prior year sales by participating brands.",
      "attributes": [
        {
          "type": "program_sheet",
          "value": "",
          "label": "2026_BASF_Retailer_Program_Potential_Earnings.pdf"
        },
        {
          "type": "program_request_id",
          "value": "59",
          "label": "AgVend Request Id"
        }
      ],
      "time_frame": "2026",
      "key_dates": [],
      "start_date": "2025-10-01",
      "end_date": "2026-09-30",
      "sku_keys": [],
      "time_periods": [],
      "transaction_types": [],
      "program_supplier_key": "basf",
      "version": "2026-02-24T18:41:15Z",
      "qualifications": [],
      "qualifier": null,
      "external_ids": [
        {
          "type": "string",
          "key": "program_request_id",
          "value": "59"
        }
      ],
      "verifications": [],
      "offers": [
        {
          "key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000.ilevo",
          "label": "2025 - 2026 BASF → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000 → ILEVO",
          "attributes": [],
          "sku_keys": [
            "ilevo_seed_treatment_15_gal_59023128",
            "ilevo_seed_treatment_2.5_gal_59023127",
            "xitavo_soybean_seed_unit"
          ],
          "time_periods": [
            {
              "key": "incentive_period",
              "label": "Earning time period",
              "start_date": "2025-10-01",
              "start_date_label": "Purchase start",
              "end_date": "2026-09-30",
              "end_date_label": "Purchase deadline"
            }
          ],
          "transaction_types": [
            "retailer_sales_to_growers"
          ],
          "calculator_key": "dollars_per_coverage_unit",
          "qualifications": [],
          "qualifier": null,
          "strategy_key": "stacked",
          "incentive": {
            "sku_sets": [
              {
                "key": "seed",
                "period_key": "incentive_period",
                "transaction_type": "retailer_sales_to_growers",
                "conversion": {
                  "coverage_unit": "acre",
                  "rates": [
                    {
                      "sku_key": "xitavo_soybean_seed_unit",
                      "rate": 1.0,
                      "from": "unit"
                    }
                  ]
                },
                "rates": [
                  {
                    "sku_key": "xitavo_soybean_seed_unit",
                    "rate": 0.0,
                    "measure": "dollars"
                  }
                ]
              },
              {
                "key": "ilevo_seed_treatment",
                "period_key": "incentive_period",
                "transaction_type": "retailer_sales_to_growers",
                "conversion": {
                  "coverage_unit": "acre",
                  "rates": [
                    {
                      "sku_key": "ilevo_seed_treatment_15_gal_59023128",
                      "rate": 0.00921875,
                      "from": "gal"
                    },
                    {
                      "sku_key": "ilevo_seed_treatment_2.5_gal_59023127",
                      "rate": 0.00921875,
                      "from": "gal"
                    }
                  ]
                },
                "rates": [
                  {
                    "sku_key": "ilevo_seed_treatment_15_gal_59023128",
                    "rate": 0.75,
                    "measure": "dollars"
                  },
                  {
                    "sku_key": "ilevo_seed_treatment_2.5_gal_59023127",
                    "rate": 0.75,
                    "measure": "dollars"
                  }
                ]
              }
            ],
            "stacks": [
              {
                "key": "seed_and_ilevo_seed_treatment",
                "label": null,
                "sku_set_keys": [
                  "seed",
                  "ilevo_seed_treatment"
                ]
              }
            ]
          }
        },
        {
          "key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000.vault_ip_plus",
          "label": "2025 - 2026 BASF → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000 → Vault Ip Plus",
          "attributes": [],
          "sku_keys": [
            "vault_ip_plus_seed_treatment_100_unit_59017726",
            "vault_ip_plus_seed_treatment_200_unit_59017860",
            "xitavo_soybean_seed_unit"
          ],
          "time_periods": [
            {
              "key": "incentive_period",
              "label": "Earning time period",
              "start_date": "2025-10-01",
              "start_date_label": "Purchase start",
              "end_date": "2026-09-30",
              "end_date_label": "Purchase deadline"
            }
          ],
          "transaction_types": [
            "retailer_sales_to_growers"
          ],
          "calculator_key": "dollars_per_coverage_unit",
          "qualifications": [],
          "qualifier": null,
          "strategy_key": "stacked",
          "incentive": {
            "sku_sets": [
              {
                "key": "seed",
                "period_key": "incentive_period",
                "transaction_type": "retailer_sales_to_growers",
                "conversion": {
                  "coverage_unit": "acre",
                  "rates": [
                    {
                      "sku_key": "xitavo_soybean_seed_unit",
                      "rate": 1.0,
                      "from": "unit"
                    }
                  ]
                },
                "rates": [
                  {
                    "sku_key": "xitavo_soybean_seed_unit",
                    "rate": 0.0,
                    "measure": "dollars"
                  }
                ]
              },
              {
                "key": "vault_ip_plus_seed_treatment",
                "period_key": "incentive_period",
                "transaction_type": "retailer_sales_to_growers",
                "conversion": {
                  "coverage_unit": "acre",
                  "rates": [
                    {
                      "sku_key": "vault_ip_plus_seed_treatment_100_unit_59017726",
                      "rate": 0.51,
                      "from": "unit"
                    },
                    {
                      "sku_key": "vault_ip_plus_seed_treatment_200_unit_59017860",
                      "rate": 0.51,
                      "from": "unit"
                    }
                  ]
                },
                "rates": [
                  {
                    "sku_key": "vault_ip_plus_seed_treatment_100_unit_59017726",
                    "rate": 0.75,
                    "measure": "dollars"
                  },
                  {
                    "sku_key": "vault_ip_plus_seed_treatment_200_unit_59017860",
                    "rate": 0.75,
                    "measure": "dollars"
                  }
                ]
              }
            ],
            "stacks": [
              {
                "key": "seed_and_vault_ip_plus_seed_treatment",
                "label": null,
                "sku_set_keys": [
                  "seed",
                  "vault_ip_plus_seed_treatment"
                ]
              }
            ]
          }
        }
      ]
    }
  ],
  "errors": []
}

POST /calculations

This endpoint has a small update to the potential_earnings structure, the field named incentive_rate_key is a non nullable string. So far a transaction could only earn once per offer but going forward a transaction can earn multiple times in an offer as long as the incentive_rate_key is unique. Effectively, potential_earnings have a primary key of transaction_id, offer_key and incentive_rate_key

This is to ensure we provide results at the smallest level, i.e. we output how much a transaction earned per stack in a given offer. (stacks[].key is the incentive_rate_key for stacked).

{
  "data": [
    {
      "participant_key": "ag_vend_austin_tx_000",
      "potential_earnings": [
        {
          "offer_key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000.ilevo",
          "offer_label": "2025 - 2026 BASF → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000 → ILEVO",
          "offer_calculator": "dollars_per_coverage_unit",
          "sku_key": "ilevo_seed_treatment_15_gal_59023128",
          "incentive_rate_key": "seed_and_ilevo_seed_treatment",
          "incentive_rate_measure": "dollars",
          "incentive_rate_value": 0.75,
          "offer_sku_pay_rate": 0.75,
          "transaction_id": "01F8ZMVJKB5XNPQ6TRDYW4EH9G",
          "transaction_type": "retailer_sales_to_growers",
          "invoice_date": "2025-10-16",
          "provided_quantity": 10.0,
          "provided_uom_key": "gal",
          "provided_amount": 4700.0,
          "incentivized_quantity": 10.0,
          "incentivized_amount": 4700.0,
          "incentive_amount": 813.56,
          "incentive_contribution_percent": 1.0,
          "incentive_effective_rate": 0.173,
          "properties": []
        },
        {
          "offer_key": "basf.2026.retailer.local.seed_treatment_soybean_pair_up.ag_vend_austin_tx_000.vault_ip_plus",
          "offer_label": "2025 - 2026 BASF → Retailer → Local → Seed Treatment Soybean Pair Up → AgVend Austin Tx 000 → Vault Ip Plus",
          "offer_calculator": "dollars_per_coverage_unit",
          "sku_key": "vault_ip_plus_seed_treatment_100_unit_59017726",
          "incentive_rate_key": "seed_and_vault_ip_plus_seed_treatment",
          "incentive_rate_measure": "dollars",
          "incentive_rate_value": 0.75,
          "offer_sku_pay_rate": 0.75,
          "transaction_id": "01GRT7B2MZXSVNF0YJKHWP2A4C",
          "transaction_type": "retailer_sales_to_growers",
          "invoice_date": "2025-10-16",
          "provided_quantity": 1000.0,
          "provided_uom_key": "unit",
          "provided_amount": 45000.0,
          "incentivized_quantity": 765.0,
          "incentivized_amount": 45000.0,
          "incentive_amount": 1125.0,
          "incentive_contribution_percent": 1.0,
          "incentive_effective_rate": 0.025,
          "properties": []
        }
      ],
      "qualification_results": []
    }
  ],
  "errors": []
}

2026-02-12

Added

All endpoints will now include the current application version as a response header (X-Calc-Version). It is our recommendation that you capture this version (along with request/response JSON) when making requests. This will allow us to more readily track down bug if/when provided.

Versions are essentially time-stamps in the form of: 2026-02-12--17-51-52Z

2026-01-27

Added

Our documentation now includes a Coming Soon page. This will be updated regularly to describe features that we are working on. It will typically include things like examples of JSON input/output from our engine. The example should be considered drafts and are subject to change. The intent is for you to be able to plan for changes to your system, mock-up design changes, or provoke asking our team questions on the new feature.

2026-01-26

Added

A new strategy named stepped has been added. Programs configured with this strategy will have a strategy_key = stepped.

GET /programs

This endpoint will output offers with stepped strategy with a new structure for incentive like shown below. Unlike standard strategy, stepped does not support incentives: [...], instead it has an object incentive: {} The incentive object has three high level keys: - filters[]: This defines the transactions that will be earning in the given offer by using period_key, sku_keys and transaction_type - threshold_definition: This defines the criteria that determines which rate is applicable for given request. The structure for this object changes depending on its type; aggregated_amount or aggregated_quantity will have the same attributes and is used to calculate the threshold from given transaction whereas property type indicates that the value to determine rate will be provided in the request as a property. - rates[]: This defines the scale of the stepped offer and the value resulting from threshold_definition is compared with the threshold to apply given rate value. The key for the rate that is used for the calculation is returned as incentive_rate_key in the potential_earnings

{
    "offers": [
        {
            "key": "offer_a",
            "label": "2025 - 2026 Offer A",
            "attributes": [],
            "sku_keys": [
                "sku_a",
                "sku_b",
                "sku_c",
                "sku_d"
            ],
            "time_periods": [
                {
                    "key": "incentive_period",
                    "label": "Earning time period",
                    "start_date": "2025-10-01",
                    "start_date_label": "Purchase start",
                    "end_date": "2025-11-15",
                    "end_date_label": "Purchase deadline"
                }
            ],
            "transaction_types": [
                "retailer_purchases_from_distribution"
            ],
            "calculator_key": "percent_of_amount",
            "qualifications": [],
            "qualifier": null,
            "strategy_key": "stepped",
            "incentive": {
                "filters": [
                    {
                        "period_key": "incentive_period",
                        "sku_keys": [
                            "sku_a",
                            "sku_b"
                        ],
                        "transaction_type": "retailer_purchases_from_distribution"
                    }
                ],
                "threshold_definition": {
                    "type": "aggregated_amount",
                    "filters": [
                        {
                            "period_key": "incentive_period",
                            "sku_keys": [
                                "sku_c",
                                "sku_d"
                            ],
                            "transaction_type": "retailer_purchases_from_distribution"
                        }
                    ]
                },
                "rates": [
                    {
                        "key": "15_percent_greater_than_or_equal_to_2000",
                        "label": null,
                        "threshold": 2000.0,
                        "value": 15.0,
                        "measure": "percent"
                    },
                    {
                        "key": "10_percent_greater_than_or_equal_to_1000",
                        "label": null,
                        "threshold": 1000.0,
                        "value": 10.0,
                        "measure": "percent"
                    }
                ]
            }
        },
        {
            "key": "offer_b",
            "label": "2025 - 2026 Offer B",
            "attributes": [],
            "sku_keys": [
                "sku_a",
                "sku_b"
            ],
            "time_periods": [
                {
                    "key": "incentive_period",
                    "label": "Earning time period",
                    "start_date": "2025-10-01",
                    "start_date_label": "Purchase start",
                    "end_date": "2025-11-15",
                    "end_date_label": "Purchase deadline"
                }
            ],
            "transaction_types": [
                "retailer_purchases_from_distribution"
            ],
            "calculator_key": "percent_of_amount",
            "qualifications": [],
            "qualifier": null,
            "strategy_key": "stepped",
            "incentive": {
                "filters": [
                    {
                        "period_key": "incentive_period",
                        "sku_keys": [
                            "sku_c",
                            "sku_d"
                        ],
                        "transaction_type": "retailer_purchases_from_distribution"
                    }
                ],
                "threshold_definition": {
                    "type": "property",
                    "property": {
                        "key": "business_plan_achieved",
                        "type": "number",
                        "level": "request"
                    }
                },
                "rates": [
                    {
                        "key": "1.88_percent_greater_than_or_equal_to_75",
                        "label": null,
                        "threshold": 75.0,
                        "value": 1.88,
                        "measure": "percent"
                    },
                    {
                        "key": "1.9_percent_greater_than_or_equal_to_85",
                        "label": null,
                        "threshold": 85.0,
                        "value": 1.9,
                        "measure": "percent"
                    },
                    {
                        "key": "1.92_percent_greater_than_or_equal_to_96",
                        "label": null,
                        "threshold": 96.0,
                        "value": 1.92,
                        "measure": "percent"
                    },
                    {
                        "key": "1.94_percent_greater_than_or_equal_to_97",
                        "label": null,
                        "threshold": 97.0,
                        "value": 1.94,
                        "measure": "percent"
                    },
                    {
                        "key": "1.96_percent_greater_than_or_equal_to_98",
                        "label": null,
                        "threshold": 98.0,
                        "value": 1.96,
                        "measure": "percent"
                    },
                    {
                        "key": "1.98_percent_greater_than_or_equal_to_99",
                        "label": null,
                        "threshold": 99.0,
                        "value": 1.98,
                        "measure": "percent"
                    },
                    {
                        "key": "2_percent_greater_than_or_equal_to_100",
                        "label": null,
                        "threshold": 100.0,
                        "value": 2.0,
                        "measure": "percent"
                    }
                ]
            }
        }
    ]
}

POST /calculations

This endpoint has a small addition to the potential_earnings structure, a field named incentive_rate_key which is an optional string. For standard offers it is the incentive[].key whereas for stepped it is the rate[].key, this helps the requestor know which rate or incentive is applied for the incentive calculation of given offer.

{
  "data": [
    {
      "participant_key": "ag_vend_austin_tx_000",
      "potential_earnings": [
        {
          "offer_key": "offer_a",
          "offer_label": "2025 - 2026 Offer A",
          "offer_calculator": "percent_of_amount",
          "sku_key": "sku_a",
          "incentive_rate_key": "15_percent_greater_than_or_equal_to_2000",
          "incentive_rate_measure": "percent",
          "incentive_rate_value": 15.0,
          "offer_sku_pay_rate": 0.15,
          "transaction_id": "01JAD80XDZGZNTYDRV4H56221W",
          "transaction_type": "retailer_purchases_from_distribution",
          "invoice_date": "2025-10-24",
          "provided_quantity": 1570.0,
          "provided_uom_key": "gal",
          "provided_amount": 86350.0,
          "incentivized_quantity": 1570.0,
          "incentivized_amount": 78500.0,
          "incentive_amount": 11775.0,
          "incentive_contribution_percent": 0.146,
          "incentive_effective_rate": 0.15,
          "properties": []
        },
      ],
    }
  ],
}

2025-12-29

Added

POST /calculations now supports evaluating qualifications based on a property value:

Example property in qualification request

  • Currently request level properties are supported
  • Properties can be of type boolean or number
{
  "participant_key": "ag_vend_austin_tx_000",
  "properties": [
    {
      "key": "foo_property",
      "type": "boolean",
      "value": true
    },
    {
      "key": "bar_property",
      "type": "number",
      "value": 95
    }
  ],
  "entities": [...],
  "relationships": [...]
}

Example qualification results

{
  "data": [
    {
      "participant_key": "ag_vend_austin_tx_000",
      "potential_earnings": [...],
      "qualification_results": [
        {
          "offer_key": "corteva.2026.retailer.local.local_offer.cpi_hastings_ne_073.base",
          "qualification_key": "foo_property_qualification",
          "met": true,
          "waived": false,
          "target": 0.0,
          "operator": "equal_to",
          "actual": 0.0,
          "difference": 0.0
        },
        {
          "offer_key": "corteva.2026.retailer.local.local_offer.cpi_hastings_ne_073.base",
          "qualification_key": "bar_property_qualification",
          "met": true,
          "waived": false,
          "target": 90.0,
          "operator": "greater_than_or_equal_to",
          "actual": 95.0,
          "difference": 5.0
        }
      ]
    }
  ],
  "errors": []
}

2025-12-02

Added

POST /calculations now (optionally) accepts a seller attribute on transaction. The seller attribute should be included when a calculation request is made for a program_supplier_type of distributor.


POST /calculations now (optionally) accepts a seller attribute on transaction. The seller attribute should be included when a calculation request is made for a program_supplier_type of distributor.

Example Request

{
  "participant_key": "agtegra",
  "entities": [
    {
      "id": "350FEN",
      "properties": [],
      "transactions": [
        {
          "transaction_id": "01JAD80XDZM296AGN3T33ZWMJF",
          "transaction_type": "retailer_purchases_from_distribution",
          "invoice_date": "2022-09-16",
          "sku_key": "keystone_la_nxt_herbicide_bulk_1009512",
          "quantity": 2000007.0,
          "uom_key": "gal",
          "amount": 1025444,
          "seller": {
            "key": "winfield"
          },
          "properties": []
        }
      ]
    }
  ],
  "relationships": [],
  "properties": []
}

Example Request

{
  "participant_key": "agtegra",
  "entities": [
    {
      "id": "350FEN",
      "properties": [],
      "transactions": [
        {
          "transaction_id": "01JAD80XDZM296AGN3T33ZWMJF",
          "transaction_type": "retailer_purchases_from_distribution",
          "invoice_date": "2022-09-16",
          "sku_key": "keystone_la_nxt_herbicide_bulk_1009512",
          "quantity": 2000007.0,
          "uom_key": "gal",
          "amount": 1025444,
          "seller": {
            "key": "winfield"
          },
          "properties": []
        }
      ]
    }
  ],
  "relationships": [],
  "properties": []
}

2025-11-24

Changed

GET /enrollments will now include a program_supplier_type which will be either:

  • basic_manufacturer
  • distributor

When the type is distributor, this is an indication that seller should be included on transactions.


GET /enrollments will now include a program_supplier_type which will be either:

  • basic_manufacturer
  • distributor

When the type is distributor, this is an indication that seller should be included on transactions.

2025-11-05

Changed

BREAKING CHANGE POST /calculations now requires the program_supplier_key parameter. This parameter was previously optional but was already being submitted in most if not all requests.


BREAKING CHANGE POST /calculations now requires the program_supplier_key parameter. This parameter was previously optional but was already being submitted in most if not all requests.

2025-11-04

Changed

GET /skus no longer requires the manufacturer_key parameter. This is especially helpful in the context of distributor programs which can span multiple product suppliers.


GET /skus no longer requires the manufacturer_key parameter. This is especially helpful in the context of distributor programs which can span multiple product suppliers.

2025-09-30

Added

GET /programs now includes qualification attributes.

      "attributes": [
        {
          "type": "program_sheet",
          "value": "2025-2026 Corteva Retail Offer Book_Digital.pdf",
          "label": ""
        },
        {
          "type": "program_request_id",
          "value": "37",
          "label": "AgVend Request Id"
        },
        {
          "type": "program_request_id",
          "value": "45",
          "label": "AgVend Request Id"
        }
      ],

GET /programs now includes qualification attributes.

      "attributes": [
        {
          "type": "program_sheet",
          "value": "2025-2026 Corteva Retail Offer Book_Digital.pdf",
          "label": ""
        },
        {
          "type": "program_request_id",
          "value": "37",
          "label": "AgVend Request Id"
        },
        {
          "type": "program_request_id",
          "value": "45",
          "label": "AgVend Request Id"
        }
      ],

2025-09-24

Added

GET /programs now includes a version attribute. Version is a String in the format of a ISO-8601 using Zulu time short-hand (Z) for UTC.


GET /programs now includes a version attribute. Version is a String in the format of a ISO-8601 using Zulu time short-hand (Z) for UTC.

2025-09-22

Fixed

  • Increased POST body request size limit. The previous (default) limit was causing unexpected errors when larger requests to POST /calculations were submitted.
  • POST /calculations will now fail with a 422 when a request includes (exact) duplicate transactions

  • Increased POST body request size limit. The previous (default) limit was causing unexpected errors when larger requests to POST /calculations were submitted.
  • POST /calculations will now fail with a 422 when a request includes (exact) duplicate transactions

2025-06-20

Added

POST /calculations now includes the ability to waive qualifications. When a qualification is waived, it is assumed as true when evaluating the qualifier.

The qualification waiver is passed in as a property at the highest level of the request with key:waive and type: waive_qualifications which enforces the value to be an array of an object containing program_key, offer_key - optional and qualification_key.

{
  "participant_key": "foo",
  "entities": [...],
  "relationships": [...].
  "properties": [
     {
      "key": "waive",
      "type": "waive_qualifications",
      "value": [
        {
          "program_key": "corteva.2024.national.retail_stocking",
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "qualification_key": "initial_period_minimum_qualification"
        },
        {
          "program_key": "abc",
          "qualification_key": "participated_in_training"
        }
      ]
    }
   ]
}

This request will result in an output like this:

  "potential_earnings": [
        {
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "offer_label": "2023 - 2024 Corteva → National → Retail Stocking → Biologicals → Base ",
          "offer_calculator": "percent_of_amount",
          "sku_key": "utrisha_n_biostimulant_12.5_lb_1409466",
          "incentive_rate_measure": "percent",
          "incentive_rate_value": 5.0,
          "offer_sku_pay_rate": 0.05,
          "transaction_id": "01JAD80XDZ3EYJSQF8J8P7GFR4",
          "transaction_type": "retailer_purchases_from_distribution",
          "invoice_date": "2024-03-07",
          "provided_quantity": 30.0,
          "provided_uom_key": "lb",
          "provided_amount": 109272.6015625,
          "incentivized_quantity": 30.0,
          "incentivized_amount": 1134.0,
          "incentive_amount": 56.7,
          "incentive_contribution_percent": 1.0,
          "incentive_effective_rate": 0.05,
          "properties": []
        },
        ...
      ],
      "qualification_results": [
        {
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "qualification_key": "initial_period_minimum_qualification",
          "met": false,
          "waived": true,
          "target": 20000.0,
          "operator": "greater_than_or_equal_to",
          "actual": 1134.0
        },
        {
          "offer_key": "corteva.2024.local.agtegra.retail_advantage.biocontrol",
          "qualification_key": "purchase_minimum_amount_qualification",
          "met": true,
          "waived": false,
          "target": 100000.0,
          "operator": "greater_than_or_equal_to",
          "actual": 4990495.51
        }
        ...
      ]

One of the primary use cases of this feature is to waive qualifications that are deemed "assume completed". These are typically qualifications for non-transaction based activity (e.g. "attended a training"). These qualification will have an additional attribute indicating that they should be waived. You will see this attribute in the GET /programs output on either program or offer qualifications:

{
  "qualifications": [
    {
      "type": "property",
      "key": "attended_training_qualification",
      "label": "Attended Training Qualification",
      "operator": "equal_to",
      "value": true,
      "attributes": [
        {
          "type": "waive_qualifications",
          "value": "assume_complete",
          "label": "Safe to mark as assumed complete - not transaction-driven"
        }
      ],
      "property": {
        "key": "attended_training",
        "type": "boolean",
        "level": "request"
      }
    }
  ]
}

POST /calculations now includes the ability to waive qualifications. When a qualification is waived, it is assumed as true when evaluating the qualifier.

The qualification waiver is passed in as a property at the highest level of the request with key:waive and type: waive_qualifications which enforces the value to be an array of an object containing program_key, offer_key - optional and qualification_key.

{
  "participant_key": "foo",
  "entities": [...],
  "relationships": [...].
  "properties": [
     {
      "key": "waive",
      "type": "waive_qualifications",
      "value": [
        {
          "program_key": "corteva.2024.national.retail_stocking",
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "qualification_key": "initial_period_minimum_qualification"
        },
        {
          "program_key": "abc",
          "qualification_key": "participated_in_training"
        }
      ]
    }
   ]
}

This request will result in an output like this:

  "potential_earnings": [
        {
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "offer_label": "2023 - 2024 Corteva → National → Retail Stocking → Biologicals → Base ",
          "offer_calculator": "percent_of_amount",
          "sku_key": "utrisha_n_biostimulant_12.5_lb_1409466",
          "incentive_rate_measure": "percent",
          "incentive_rate_value": 5.0,
          "offer_sku_pay_rate": 0.05,
          "transaction_id": "01JAD80XDZ3EYJSQF8J8P7GFR4",
          "transaction_type": "retailer_purchases_from_distribution",
          "invoice_date": "2024-03-07",
          "provided_quantity": 30.0,
          "provided_uom_key": "lb",
          "provided_amount": 109272.6015625,
          "incentivized_quantity": 30.0,
          "incentivized_amount": 1134.0,
          "incentive_amount": 56.7,
          "incentive_contribution_percent": 1.0,
          "incentive_effective_rate": 0.05,
          "properties": []
        },
        ...
      ],
      "qualification_results": [
        {
          "offer_key": "corteva.2024.national.retail_stocking.biologicals.base",
          "qualification_key": "initial_period_minimum_qualification",
          "met": false,
          "waived": true,
          "target": 20000.0,
          "operator": "greater_than_or_equal_to",
          "actual": 1134.0
        },
        {
          "offer_key": "corteva.2024.local.agtegra.retail_advantage.biocontrol",
          "qualification_key": "purchase_minimum_amount_qualification",
          "met": true,
          "waived": false,
          "target": 100000.0,
          "operator": "greater_than_or_equal_to",
          "actual": 4990495.51
        }
        ...
      ]

2025-06-11

Added

GET /enrollments?time_frame=<foo> endpoint has been added. It provides the program suppliers related to a participant in a given time frame.

{
  "data": [
    {
      "program_supplier_key": "corteva"
    },
    {
      "program_supplier_key": "syngenta"
    },
    {
      "program_supplier_key": "bayer"
    }
  ],
  "errors": []
}

Note: This is an object versus a simple array to leave room for any additional information that may be required for an enrollee


GET /enrollments?time_frame=<foo> endpoint has been added. It provides the program suppliers related to a participant in a given time frame.

{
  "data": [
    {
      "program_supplier_key": "corteva"
    },
    {
      "program_supplier_key": "syngenta"
    },
    {
      "program_supplier_key": "bayer"
    }
  ],
  "errors": []
}

Note: This is an object versus a simple array to leave room for any additional information that may be required for an enrollee

2025-06-07

Added

GET /programs now includes external id's when configured. The's id's can be used to link up to requests/programs defined in your system.

{
  ...
  "external_ids": [
      {
          "key": "program_request_id",
          "value": "123"
      }
    ],
  ...
}

GET /programs now includes external id's when configured. The's id's can be used to link up to requests/programs defined in your system.

{
  ...
  "external_ids": [
      {
          "key": "program_request_id",
          "value": "123"
      }
    ],
  ...
}

2025-05-30

Changed

GET /programs now includes a (fake, hard-code) value for program version.

"version": "2025-01-01--01"

GET /programs now includes a (fake, hard-code) value for program version.

"version": "2025-01-01--01"

2025-05-16

Changed

GET /skus now includes the following attributes on the Sku structure:

  • brand_key
  • brand_label
  • product_key
  • product_label

GET /skus now includes the following attributes on the Sku structure:

  • brand_key
  • brand_label
  • product_key
  • product_label