Skip to content

Changelog

All notable changes to the API will be documented here.

2026-09-25

Added

POST /calculations

Each qualification_results entry now includes a group_by array identifying the partition for that result. Entries contain field, key, and value. The array is empty when the result is not grouped.

For example, a qualification result grouped by purchaser will look like:

{
  "program_key": "example-program",
  "offer_key": "example-offer",
  "qualification_key": "minimum-purchase",
  "met": true,
  "waived": false,
  "target": 1000,
  "operator": "greater_than_or_equal_to",
  "actual": 1250,
  "difference": 250,
  "group_by": [
    {
      "field": "purchaser",
      "key": "id",
      "value": "purchaser-123"
    }
  ]
}

2026-09-24

Added

GET /programs now includes the transform used by applicable qualifications and incentives. Clients can use the transform's type, from, and based_on fields to determine which transaction value or catalog data is required when displaying programs. Unsupported qualification types return a null transform.

For example, a qualification that evaluates transaction amounts using the program redemption price includes a non-null transform:

{
  "type": "aggregated_amount",
  "key": "minimum_cp_purchases",
  "operator": "greater_than_or_equal_to",
  "value": 100000.0,
  "transform": {
    "type": "price",
    "from": "quantity",
    "based_on": "program_redemption_price"
  },
  "filters": [
    {
      "period_key": "incentive_period",
      "sku_keys": ["agri_shield_insecticide_2.5_gal_53551"],
      "transaction_type": "retailer_purchases_from_distribution"
    }
  ],
  "attributes": []
}

2026-09-23

Removed

Gated incentive earning periods

The deprecated incentive-level period_key has been removed from gated incentives. Consumers should use rates[].period_key to determine the earning period for each rate. Rates within one incentive may now use different earning periods. gate_definition.period_key is unchanged and continues to identify the gate transaction period.

A GET /programs response now returns gated incentives in this shape:

{
  "strategy_key": "gated",
  "calculator_key": "dollars_per_unit",
  "incentives": [
    {
      "key": "retailer_purchases_from_distribution_0",
      "transaction_type": "retailer_purchases_from_distribution",
      "rates": [
        {
          "sku_key": "agri_shield_insecticide_2.5_gal_53551",
          "rate": 2.0,
          "measure": "dollars",
          "period_key": "incentive_period"
        }
      ],
      "gate_definition": {
        "period_key": "order_period",
        "transaction_type": "retailer_orders_from_distribution",
        "measure": "quantity",
        "scope": "sku_key",
        "precedence": "first_in_first_out"
      }
    }
  ]
}

2026-09-22

Changed

Gated incentive earning periods

Gated incentive rates now include an optional period_key, which identifies the earning period for each rate and prepares the API for more complex gated programs. Rates within the same incentive continue to share the same gate quantity pool.

API consumers should use the rate-level period_key as the source of earning-period information. During the transition, the existing high-level GatedIncentive.period_key remains available and contains the same value as each rate's key. The high-level field is deprecated and will be removed in a future update; after that transition, rates within the same incentive can use different earning periods. The separate gate_definition.period_key remains unchanged.

A transitional GET /programs response includes both fields:

{
  "strategy_key": "gated",
  "calculator_key": "dollars_per_unit",
  "incentives": [
    {
      "key": "purchase_incentive",
      "transaction_type": "retailer_purchases_from_distribution",
      "period_key": "incentive_period" -- deprecated
      "rates": [
        {
          "sku_key": "agri_shield_insecticide_2.5_gal_53551",
          "rate": 2.0,
          "measure": "dollars",
          "period_key": "incentive_period"
        }
      ],
      "gate_definition": {
        "period_key": "order_period",
        "transaction_type": "retailer_orders_from_distribution",
        "measure": "quantity",
        "scope": "sku_key",
        "precedence": "first_in_first_out"
      }
    }
  ]
}

2026-08-28

Changed

POST /calculations gzip request bodies

POST /calculations now accepts existing JSON request documents compressed with gzip. Send Content-Encoding: gzip with Content-Type: application/json; Calc decompresses the body before validation and calculation. Uncompressed requests, including Content-Encoding: identity, retain their current behavior.

POST /calculations
Content-Type: application/json
Content-Encoding: gzip

The request body is the gzip-compressed form of the existing calculation JSON payload. This can reduce transfer time for large calculation requests; no migration is required for clients that continue to send plain JSON.

A gzip body must decompress to a UTF-8 JSON document within the 256 MiB request limit. Invalid gzip bodies return 400 Bad Request; unsupported or multiple Content-Encoding values return 415 Unsupported Media Type.

2026-08-24

Added

TransactionType now includes the inventory-balance expression beginning_inventory + retailer_purchases_from_distribution - ending_inventory. This value can appear where program configuration describes the transaction types used by an offer.

POST /calculations request transactions and potential_earnings responses now use the new SimpleTransactionType schema. It contains the supported source transaction values and intentionally excludes the inventory-balance expression: clients submit the source inventory and purchase transactions, and the calculation derives the composite value internally before returning prorated earnings against those source transactions.

Existing transaction values are unchanged. Clients that generate types from docs/openapi.json should regenerate them to pick up the new SimpleTransactionType schema and updated references.

2026-08-17

Added

GET /skus includes historical prices

The GET /skus response now includes an additive all_prices array containing the complete price history for each SKU, including historical and current prices. Entries include their existing starts_on and ends_on dates so clients can distinguish historical from current prices and preserve prior values when prices change.

The existing current_prices array is unchanged and remains available for clients that only need currently open-ended prices. No migration is required for existing clients; clients that want historical pricing can begin reading all_prices.

2026-08-07

Added

GET /calculations/requirements now includes time_frame metadata for the requested supplier season. This gives users the season value, display label, and start and end dates alongside the calculation requirements.

{
  "data": [
    { 
      ...
      "time_frame": {
        "value": "2026",
        "start_date": "2025-10-01",
        "end_date": "2026-09-30",
        "label": "Market Year 2025 - 2026"
      },
    }
  ],
}

2026-07-30

Added

gated offers are now supported by POST /calculations. A gated incentive uses qualifying gate transactions to unlock a matching quantity of earning transactions for the same SKU. Gate and earning quantities are matched in first-in, first-out order, so only the quantity covered by the gate earns an incentive. For each earning transaction, only matching gate transactions dated before that earning transaction are considered.

GET /programs

Gated offers return strategy_key: "gated" and expose each incentive's gate definition. Gate definitions require a gate period and transaction type, and use quantity, sku_key, and first_in_first_out semantics:

{
  "strategy_key": "gated",
  "incentives": [
    {
      "key": "purchase_gate",
      "transaction_type": "retailer_purchases_from_distribution",
      "gate_definition": {
        "period_key": "order_period",
        "transaction_type": "retailer_orders_from_distribution",
        "measure": "quantity",
        "scope": "sku_key",
        "precedence": "first_in_first_out"
      }
    }
  ]
}

For example, a program can pay a retailer for qualifying retailer_purchases_from_distribution transactions only when it has a matching quantity of the same SKU in retailer_orders_from_distribution transactions dated before the purchase. A 100-unit qualifying order unlocks earnings for up to 100 units of matching purchases; purchases beyond that quantity do not earn until additional qualifying orders are provided.

POST /calculations

Gated incentives support dollars_per_unit and percent_of_amount calculators. Calculation results report only the unlocked portion of each earning transaction in incentivized_quantity, incentivized_amount, and incentive_amount. Transactions that have no matching gate quantity do not produce potential earnings.

This is additive: existing strategy behavior is unchanged.

2026-07-15

Added

Adds the following program related label fields to GET /programs.

  • channel_label
  • audience_label
  • program_name_label
  • program_supplier_label
{
  "data": [
    {
      "key": "bradley.2026.retailer.local.bradley_local.tcp_austin_tx_999",
      "label": "2025 - 2026 Bradley → Retailer → Local → Bradley Local → TCP Austin TX 999",
      "summary": "Retailers earn varying incentives when selling Bradley products in 2026 season:",
      "description": "Retailers can earn varying incentives when selling specified Bradley products",
      "attributes": [
        {
          "type": "program_sheet",
          "value": "",
          "label": "Bradley 2025-26 Local Program"
        },
        {
          "type": "program_request_id",
          "value": "1",
          "label": "AgVend Request Id"
        }
      ],
      "time_frame": "2026",
      "channel": "retailer",
      "channel_label": "Retailer",
      "audience": "local",
      "audience_label": "Local",
      "program_name": "bradley_local",
      "program_name_label": "Bradley Local",
      "key_dates": [],
      "start_date": "2025-10-01",
      "end_date": "2026-09-30",
      "sku_keys": [],
      "time_periods": [],
      "transaction_types": [],
      "properties": [],
      "program_supplier_key": "bradley",
      "program_supplier_label": "Bradley",
      "version": "2026-07-14T20:38:06Z",
      ...

2026-07-06

Added

A new state query parameter has been added to GET /programs, allowing clients to filter programs by their lifecycle state. A new pending state is introduced alongside the existing released state, so programs that are not yet ready for release can be deployed and queried separately.

GET /programs

The state query parameter is optional and defaults to released, preserving existing behavior. No changes to the response JSON shape — the response body is identical regardless of which state is requested.

GET /programs?program_supplier_key=...&time_frame=2026

Returns released programs (unchanged default).

GET /programs?program_supplier_key=...&time_frame=2026&state=pending

Returns programs in the pending state — those deployed but not yet ready for release.

Invalid state values return a 400 Bad Request error.

2026-06-29

Added

Add GET /calculations/requirements

A new endpoint is added to help with request-construction fields that are nested under each returned program and offer.

GET /calculations/requirements?program_supplier_key=...&time_frame=...
participant-key: ...

The endpoint aggregates requirements over all programs returned for:

  • the participant-key header
  • the program_supplier_key query parameter
  • the time_frame query parameter

The response combines requirements from matching programs and offers into a single result. It includes:

  • the earliest start_date and latest end_date
  • all relevant transaction_types
  • all relevant sku_keys
  • standard transaction fields and their required attributes
  • program-specific properties at the request, entity, and transaction levels

Transaction fields represent standard industry data such as seller and purchaser. required_attributes identifies the minimum nested data required for a field, such as seller.key or purchaser.id. transaction_types identifies which transactions require that field.

Transaction and request properties represent program-specific data that is not part of the standard transaction structure, such as business_plan_achieved. Each property includes its expected key and data type.

Clients may include transaction fields beyond those listed in the response. Including commonly available fields on every transaction can reduce program-specific conditional logic in the client and will not cause validations errors.

When omit_transaction_when_missing is true, a transaction missing the specified field, attribute, or property is omitted from the calculation rather than causing the entire calculation request to fail.

Clients should validate that the listed fields, attributes, and properties are present before submitting a calculation. Missing requirement data can cause qualifying transactions or conditions to be omitted, resulting in calculated potential earnings that do not reflect the participant's true potential.

This endpoint replaces the need to derive calculation requirements from separate program related responses (i.e. GET /programs and GET /programs/skus). It also returns the participant-scoped sku_keys needed to construct a calculation request.

{
  "data": [
    {
      "transaction_requirements": {
        "fields": [
          {
            "field": "seller",
            "required_attributes": [
              "key"
            ],
            "transaction_types": [
              "retailer_purchases_from_distribution",
              "retailer_sales_to_growers"
            ],
            "omit_transaction_when_missing": true
          },
          {
            "field": "purchaser",
            "required_attributes": [
              "id"
            ],
            "transaction_types": [
              "retailer_purchases_from_distribution"
            ],
            "omit_transaction_when_missing": true
          }
        ],
        "properties": [
          {
            "key": "invoice_number",
            "type": "string",
            "transaction_types": [
              "retailer_purchases_from_distribution",
              "retailer_sales_to_growers"
            ],
            "omit_transaction_when_missing": true
          }
        ]
      },
      "entity_requirements": [],
      "request_requirements": {
        "properties": [
          {
            "key": "bussiness_plan_achieved",
            "type": "number"
          }
        ]
      },
      "start_date": "2025-09-01",
      "end_date": "2026-08-31",
      "transaction_types": [
        "retailer_purchases_from_distribution",
        "retailer_sales_to_growers"
      ],
      "sku_keys": [
        "keystone_la_nxt_herbicide_bulk_1009512",
        "resicore_xl_herbicide_bulk_1364786"
      ]
    }
  ],
  "errors": [],
  "meta": {
    "api_version": "v1"
  }
}

2026-06-17

Added

A new transaction type (retailer_orders_from_distribution) has been added to represent purchase orders from the retailer.

POST /calculations

Any transactions that fall into this category can now be included in the calculation request and will be used to calculate any programs that have been configured to use them.

{
  "participant_key": "ag_vend_austin_tx_000",
  "request_id": "",
  "properties": [],
  "entities": [
    {
      "id": "41eef1b3-19f2-49f1-8926-2ffbea246a97",
      "properties": [],
      "transactions": [
        {
          "transaction_id": "order-38790872-item-100681154",
          "transaction_type": "retailer_orders_from_distribution",
          "sku_key": "baythroid_xl_insecticide_1_gal_5960389",
          "uom_key": "gal",
          "quantity": 8.0,
          "amount": 1252.96,
          "invoice_date": "2022-09-01",
          "properties": [],
          "purchaser": {}
        }
       ]
    }
  ],
  "relationships": []
}

2026-06-12

Added

A new field has been added to the programs/offers object: properties. This field boils up any properties used in the given offer or program, similar to transaction_types or sku_keys.

GET /programs

        {
            "key": "bayer.2026.retailer.national.summit_target.default",
            "label": "2025 - 2026 Bayer → Retailer → National → Summit Target → Default",
            "summary": "The Bayer Summit Target program offers retailers up to 2% for meeting their business plan supporting the sale of Bayer products",
            "description": "\n    Retailers who meet at least 75% of their 2026 business plan can earn up to 2% on the Bayer Summit qualifying products.\n    ",
            "attributes": [],
            "time_frame": "2026",
            "channel": "retailer",
            "audience": "national",
            "program_name": "summit_target",
            "key_dates": [],
            "start_date": "2025-09-01",
            "end_date": "2026-08-31",
            "sku_keys": [],
            "time_periods": [],
            "transaction_types": [ ],
            "properties": [],
            "program_supplier_key": "bayer",
            "version": "2026-06-11T14:27:53Z",
            "qualifications": [],
            "qualifier": "",
            "external_ids": [],
            "group_by": [],
            "verifications": [],
            "offers": [
                {
                    "key": "bayer.2026.retailer.national.summit_target.default.broad_acre_fungicides",
                    "label": "2025 - 2026 Bayer → Retailer → National → Summit Target → Default → Broad Acre Fungicides",
                    "attributes": [],
                    "sku_keys": [],
                    "time_periods": [
                        {
                            "key": "incentive_period",
                            "label": "Earning time period",
                            "start_date": "2025-09-01",
                            "start_date_label": "Purchase start",
                            "end_date": "2026-08-31",
                            "end_date_label": "Purchase deadline"
                        }
                    ],
                    "transaction_types": [
                        "retailer_sales_to_growers"
                    ],
                    "properties": [
                        {
                            "key": "business_plan_achieved",
                            "type": "number",
                            "level": "request"
                        }
                    ],
                    "calculator_key": "percent_of_amount",
                    "qualifications": [
                        {
                            "type": "property",
                            "key": "minimum_business_plan_achieved",
                            "label": "Minimum business plan achieved",
                            "operator": "greater_than_or_equal_to",
                            "value": 75.0,
                            "attributes": [],
                            "property": {
                                "key": "business_plan_achieved",
                                "type": "number",
                                "level": "request"
                            }
                        }
                    ],
                    "qualifier": "minimum_business_plan_achieved",
                    "strategy_key": "stepped",
                    "incentive": {
                        "filters": [
                            {
                                "period_key": "incentive_period",
                                "sku_keys": [],
                                "transaction_type": "retailer_sales_to_growers",
                                "transaction_price": null
                            }
                        ],
                        "threshold_definition": {
                            "type": "property",
                            "property": {
                                "key": "business_plan_achieved",
                                "type": "number",
                                "level": "request"
                            }
                        },
                        "rates": []
                    }
                }

2026-06-09

Added

program_key is now included on every row in both potential_earnings and qualification_results. Clients can use this field to filter results by program or aggregate incentive_amount at the program level without reverse-mapping through offer_key.

POST /calculations

potential_earnings now includes program_key after offer_key:

"potential_earnings": [
  {
    "program_key": "corteva.2026.retailer.national.corn_early_fill.default",
    "offer_key": "corteva.2026.retailer.national.corn_early_fill.default.base",
    "offer_label": "...",
    ...
  }
]

qualification_results now includes program_key after offer_key:

"qualification_results": [
  {
    "program_key": "corteva.2026.retailer.national.corn_early_fill.default",
    "offer_key": "corteva.2026.retailer.national.corn_early_fill.default.rate_lock",
    "qualification_key": "...",
    ...
  }
]

2026-06-04

Added

A new field has been added to the group_by object in programs: omit_transaction_when_missing. This is defaulted to True and indicates that the transactions that do not have the required group_by info for a program calculation will be omitted from calculating for that program instead of the request erroring. When this field is set to False, the validation will be stricter and requests will fail with an error like:

  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "incomplete 'group_by' info: transactions of type 'retailer_sales_to_growers' are missing 'purchaser.id': [148]"
    }
  ],

GET /programs

This field will be present in the group_by definition and can be used to programmatically know when the group_by is absolutely required to be present for all relevant transactions.

        {
            "key": "bradley.2026.retailer.national.foo.default",
            "label": "2025 - 2026 Bradley → Retailer → National → Foo → Default",
            "summary": "...",
            "description": "...",
            "attributes": [...],
            "time_frame": "2026",
            "channel": "retailer",
            "audience": "national",
            "program_name": "foo",
            "key_dates": [],
            "start_date": "2025-09-01",
            "end_date": "2026-08-31",
            "sku_keys": [],
            "time_periods": [],
            "transaction_types": [],
            "program_supplier_key": "bradley",
            "version": "2026-06-04T14:15:55Z",
            "qualifications": [],
            "qualifier": null,
            "external_ids": [],
            "group_by": [
                {
                    "transaction_type": "retailer_sales_to_growers",
                    "field": "purchaser",
                    "key": "id",
                    "type": "string",
                    "omit_transaction_when_missing": true
                }
            ],
            "verifications": [],
            "offers": [...]
          }

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:

          "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