Using PATCH and PUT /campaigns
On this page we will document the use cases and when to use the PATCH API call versus PUT to update campaigns via API. When changes are needed to campaigns, doing a GET followed by a PUT to replace the campaign with the needed changes is the safest approach to maintain data integrity.
PATCH can be used as well for quick updates to keys such as status or details.name, but will have impacts on non-scalar values throughout the payload.
Consider this Discount Products campaign with three tags in the details.tag array and two redemption partners in the partners.redemption array.
GET /campaigns/{campaignId}
{
"id": "102789176",
"type": "DISCOUNT_PRODUCTS",
"status": "DRAFT",
"class": "COUPON",
"details": {
"name": "1.00 off a product",
"alternativeName": "",
"description": "",
"alternativeDescription": "",
"printerMessage": null,
"screenMessage": null,
"tags": [
"Tag1",
"Tag2",
"Tag3"
],
"startDate": "2026-05-14 00:00:00",
"endDate": "2026-12-31 23:59:00",
"mode": "OPEN"
},
"settings": {
"tokenProvider": "EES",
"tokenFormat": "000000001",
"walletEnabled": true,
"issuanceMethod": null,
"accountClientType": "OFFER",
"defaultAccountClientState": "LOADED"
},
"partners": {
"creation": [],
"redemption": [
{
"partner": "338781",
"redemptionLimit": null
},
{
"partner": "339191",
"redemptionLimit": null
}
]
},
"rules": {
"creation": {
"campaignLimit": null,
"consumerLimit": null,
"consumerLimitActive": 1,
"windows": {
"active": false
}
},
"adjudication": {
"excludedProducts": null
},
"verification": {
"lock": false,
"lockOnVerify": true
},
"redemption": {
"maxRedemptionsPerPeriod": null,
"campaignLimit": null,
"couponLimit": 1,
"allowOverride": null,
"allowAccountOverride": true,
"maximumAccountUsage": null,
"maximumDiscountableRelatedContents": null,
"maximumAccountsPerTransaction": null,
"windows": {
"active": false
},
"dates": {
"exclusion": {
"active": false
}
},
"timeBetweenRedemptions": null,
"timeBetweenStamps": null,
"allowMultipleRedeem": null,
"isHiddenFromRelatedWallets": false,
"redeemableOutsideOwningWalletWithIdentity": false,
"redeemableOutsideOwningWalletWithoutIdentity": false
},
"refund": {
"refundable": true,
"unredeemable": false
},
"locations": null,
"expiry": {
"type": "CAMPAIGN_END",
"valueType": null,
"value": null,
"date": null
},
"start": null,
"graceAmount": null,
"useLocalTime": {
"active": true
},
"maxCreditsPerPeriod": null
},
"windows": {
"creation": [],
"redemption": []
},
"dates": {
"redemption": {
"redemption": [],
"exclusion": []
}
},
"relationships": null,
"reference": "102789176",
"offer": {
"offerType": "VARIABLE_AMOUNT_OFF_PRODUCTS",
"qualification": {
"locations": {
"banner1": {
"included": {
"locationIdentifiers": null,
"locationTags": null
},
"excluded": {
"locationIdentifiers": null,
"locationTags": null
}
}
},
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678"
]
},
"excluded": null
},
"minimumProductSpend": 1,
"minimumUnits": 1,
"maximumUnits": 1
}
]
}
},
"globalProductRestrictions": {
"enabled": true
},
"tenders": null,
"identityTypes": null
},
"reward": {
"basket": null,
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678"
]
},
"excluded": null
},
"value": {
"interval": null,
"standard": {
"percentageAmount": null,
"allFree": false,
"discountAmount": 100,
"finalAmount": null
}
},
"maximumNumberOfUnits": 1,
"minimumNumberOfUnits": 1
}
]
}
}
},
"promoId": null
},
"version": 2,
"dateCreated": "2026-05-14T17:45:32+00:00",
"lastUpdated": "2026-05-14T17:45:32+00:00",
"lastUpdatedBy": 1
}PATCH
If simple changes to the campaign are needed for non-scalar values, PATCH can be a useful API. Let's just update the status, name, startDate and endDate using PATCH /campaigns/campaignId.
{
"status": "ACTIVE",
"details": {
"name": "1.00 off produce",
"startDate": "2026-05-12 00:00:00",
"endDate": "2026-06-30 23:59:00"
}
}{
"id": "102789176",
"type": "DISCOUNT_PRODUCTS",
"status": "ACTIVE",
"class": "COUPON",
"details": {
"name": "1.00 off produce",
"alternativeName": "",
"description": "",
"alternativeDescription": "",
"printerMessage": null,
"screenMessage": null,
"tags": [
"Tag1",
"Tag2",
"Tag3"
],
"startDate": "2026-05-12 00:00:00",
"endDate": "2026-06-30 23:59:00",
"mode": "OPEN"
},
"settings": {
"tokenProvider": "EES",
"tokenFormat": "000000001",
"walletEnabled": true,
"issuanceMethod": null,
"accountClientType": "OFFER",
"defaultAccountClientState": "LOADED"
},
"partners": {
"creation": [],
"redemption": [
{
"partner": "338781",
"redemptionLimit": null
},
{
"partner": "339191",
"redemptionLimit": null
}
]
},
"rules": {
"creation": {
"campaignLimit": null,
"consumerLimit": null,
"consumerLimitActive": 1,
"windows": {
"active": false
}
},
"adjudication": {
"excludedProducts": null
},
"verification": {
"lock": false,
"lockOnVerify": true
},
"redemption": {
"maxRedemptionsPerPeriod": null,
"campaignLimit": null,
"couponLimit": 1,
"allowOverride": null,
"allowAccountOverride": true,
"maximumAccountUsage": null,
"maximumDiscountableRelatedContents": null,
"maximumAccountsPerTransaction": null,
"windows": {
"active": false
},
"dates": {
"exclusion": {
"active": false
}
},
"timeBetweenRedemptions": null,
"timeBetweenStamps": null,
"allowMultipleRedeem": null,
"isHiddenFromRelatedWallets": false,
"redeemableOutsideOwningWalletWithIdentity": false,
"redeemableOutsideOwningWalletWithoutIdentity": false
},
"refund": {
"refundable": true,
"unredeemable": false
},
"locations": null,
"expiry": {
"type": "CAMPAIGN_END",
"valueType": null,
"value": null,
"date": null
},
"start": null,
"graceAmount": null,
"useLocalTime": {
"active": true
},
"maxCreditsPerPeriod": null
},
"windows": {
"creation": [],
"redemption": []
},
"dates": {
"redemption": {
"redemption": [],
"exclusion": []
}
},
"relationships": null,
"reference": "102789176",
"offer": {
"offerType": "VARIABLE_AMOUNT_OFF_PRODUCTS",
"qualification": {
"locations": {
"banner1": {
"included": {
"locationIdentifiers": null,
"locationTags": null
},
"excluded": {
"locationIdentifiers": null,
"locationTags": null
}
}
},
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678"
]
},
"excluded": null
},
"minimumProductSpend": 1,
"minimumUnits": 1,
"maximumUnits": 1
}
]
}
},
"globalProductRestrictions": {
"enabled": true
},
"tenders": null,
"identityTypes": null
},
"reward": {
"basket": null,
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678"
]
},
"excluded": null
},
"value": {
"interval": null,
"standard": {
"percentageAmount": null,
"allFree": false,
"discountAmount": 100,
"finalAmount": null
}
},
"maximumNumberOfUnits": 1,
"minimumNumberOfUnits": 1
}
]
}
}
},
"promoId": null
},
"version": 2,
"dateCreated": "2026-05-14T17:45:32+00:00",
"lastUpdated": "2026-05-14T18:09:47+00:00",
"lastUpdatedBy": 1
}With this method, only these four keys will be updated.
Sometimes values in an array need to be updated, such as details.tags or the product UPCs within offer qualification and reward objects. When calling the PATCH API, arrays are updated using an index-based replacement. The process compares the new array to the original by position: existing elements at shared indices are overwritten with new values, while any elements at additional indices in the new array are appended to the original.
Example:
{
"details": {
"name": "1.00 off produce",
"tags": [
"Tag1",
"Tag2",
"Tag3"
]
}
}{
"details": {
"name": "1.00 off produce",
"tags": [
"Tag4",
"Tag5"
]
}
}PATCH /campaigns/campaignId Response
{
`...`
"details": {
"name": "1.00 off produce",
"alternativeName": "",
"description": "",
"alternativeDescription": "",
"printerMessage": null,
"screenMessage": null,
"tags": [
"Tag3",
"Tag4",
"Tag5"
],
"startDate": "2026-05-12 00:00:00",
"endDate": "2026-06-30 23:59:00",
"mode": "OPEN"
},
`...`As a result of this PATCH call, the API replaced Tag1 (in position 1) with Tag4 and replaced Tag2 (in position 2) with Tag5. Tag3 was left unchanged due to no value being in position 3 of the tags on the PATCH request.
If you want the array to be completely replaced with your new values, use the PUT /campaigns/{campaignId} endpoint instead.
PUT
The PUT method replaces the entire campaign payload. When calling this API, it is best practice to do a GET /campaigns/{campaignId} call to get the most recent version of the campaign. When preparing the PUT call, the following keys cannot be updated when you replace a campaign:
- id
- reference
- dateCreated
- lastUpdated
- lastUpdatedBy
Using the same example, lets update the campaign with the following tags and products in the qualification and reward objects:
- Adding new tags of Tag4 and Tag5
- Adding new product UPC of 234567
GET /campaigns/{campaignId} Request
{
"type": "DISCOUNT_PRODUCTS",
"status": "ACTIVE",
"class": "COUPON",
"details": {
"name": "1.00 off produce",
"alternativeName": "",
"description": "",
"alternativeDescription": "",
"printerMessage": null,
"screenMessage": null,
"tags": [
"Tag1",
"Tag2",
"Tag3",
"Tag4",
"Tag5"
],
"startDate": "2026-05-12 00:00:00",
"endDate": "2026-06-30 23:59:00",
"mode": "OPEN"
},
"settings": {
"tokenProvider": "EES",
"tokenFormat": "000000001",
"walletEnabled": true,
"issuanceMethod": null,
"accountClientType": "OFFER",
"defaultAccountClientState": "LOADED"
},
"partners": {
"creation": [],
"redemption": [
{
"partner": "338781",
"redemptionLimit": null
},
{
"partner": "339191",
"redemptionLimit": null
}
]
},
"rules": {
"creation": {
"campaignLimit": null,
"consumerLimit": null,
"consumerLimitActive": 1,
"windows": {
"active": false
}
},
"adjudication": {
"excludedProducts": null
},
"verification": {
"lock": false,
"lockOnVerify": true
},
"redemption": {
"maxRedemptionsPerPeriod": null,
"campaignLimit": null,
"couponLimit": 1,
"allowOverride": null,
"allowAccountOverride": true,
"maximumAccountUsage": null,
"maximumDiscountableRelatedContents": null,
"maximumAccountsPerTransaction": null,
"windows": {
"active": false
},
"dates": {
"exclusion": {
"active": false
}
},
"timeBetweenRedemptions": null,
"timeBetweenStamps": null,
"allowMultipleRedeem": null,
"isHiddenFromRelatedWallets": false,
"redeemableOutsideOwningWalletWithIdentity": false,
"redeemableOutsideOwningWalletWithoutIdentity": false
},
"refund": {
"refundable": true,
"unredeemable": false
},
"locations": null,
"expiry": {
"type": "CAMPAIGN_END",
"valueType": null,
"value": null,
"date": null
},
"start": null,
"graceAmount": null,
"useLocalTime": {
"active": true
},
"maxCreditsPerPeriod": null
},
"windows": {
"creation": [],
"redemption": []
},
"dates": {
"redemption": {
"redemption": [],
"exclusion": []
}
},
"relationships": null,
"offer": {
"offerType": "VARIABLE_AMOUNT_OFF_PRODUCTS",
"qualification": {
"locations": {
"banner1": {
"included": {
"locationIdentifiers": null,
"locationTags": null
},
"excluded": {
"locationIdentifiers": null,
"locationTags": null
}
}
},
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678",
"234567"
]
},
"excluded": null
},
"minimumProductSpend": 1,
"minimumUnits": 1,
"maximumUnits": 1
}
]
}
},
"globalProductRestrictions": {
"enabled": true
},
"tenders": null,
"identityTypes": null
},
"reward": {
"basket": null,
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678",
"234567"
]
},
"excluded": null
},
"value": {
"interval": null,
"standard": {
"percentageAmount": null,
"allFree": false,
"discountAmount": 100,
"finalAmount": null
}
},
"maximumNumberOfUnits": 1,
"minimumNumberOfUnits": 1
}
]
}
}
},
"promoId": null
},
"version": 2
}GET /campaigns/campaignId Response
{
"id": "102789176",
"type": "DISCOUNT_PRODUCTS",
"status": "ACTIVE",
"class": "COUPON",
"details": {
"name": "1.00 off produce",
"alternativeName": "",
"description": "",
"alternativeDescription": "",
"printerMessage": null,
"screenMessage": null,
"tags": [
"Tag1",
"Tag2",
"Tag3",
"Tag4",
"Tag5"
],
"startDate": "2026-05-12 00:00:00",
"endDate": "2026-06-30 23:59:00",
"mode": "OPEN"
},
"settings": {
"tokenProvider": "EES",
"tokenFormat": "000000001",
"walletEnabled": true,
"issuanceMethod": null,
"accountClientType": "OFFER",
"defaultAccountClientState": "LOADED"
},
"partners": {
"creation": [],
"redemption": [
{
"partner": "338781",
"redemptionLimit": null
},
{
"partner": "339191",
"redemptionLimit": null
}
]
},
"rules": {
"creation": {
"campaignLimit": null,
"consumerLimit": null,
"consumerLimitActive": 1,
"windows": {
"active": false
}
},
"adjudication": {
"excludedProducts": null
},
"verification": {
"lock": false,
"lockOnVerify": true
},
"redemption": {
"maxRedemptionsPerPeriod": null,
"campaignLimit": null,
"couponLimit": 1,
"allowOverride": null,
"allowAccountOverride": true,
"maximumAccountUsage": null,
"maximumDiscountableRelatedContents": null,
"maximumAccountsPerTransaction": null,
"windows": {
"active": false
},
"dates": {
"exclusion": {
"active": false
}
},
"timeBetweenRedemptions": null,
"timeBetweenStamps": null,
"allowMultipleRedeem": null,
"isHiddenFromRelatedWallets": false,
"redeemableOutsideOwningWalletWithIdentity": false,
"redeemableOutsideOwningWalletWithoutIdentity": false
},
"refund": {
"refundable": true,
"unredeemable": false
},
"locations": null,
"expiry": {
"type": "CAMPAIGN_END",
"valueType": null,
"value": null,
"date": null
},
"start": null,
"graceAmount": null,
"useLocalTime": {
"active": true
},
"maxCreditsPerPeriod": null
},
"windows": {
"creation": [],
"redemption": []
},
"dates": {
"redemption": {
"redemption": [],
"exclusion": []
}
},
"relationships": null,
"reference": "102789176",
"offer": {
"offerType": "VARIABLE_AMOUNT_OFF_PRODUCTS",
"qualification": {
"locations": {
"banner1": {
"included": {
"locationIdentifiers": null,
"locationTags": null
},
"excluded": {
"locationIdentifiers": null,
"locationTags": null
}
}
},
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678",
"234567"
]
},
"excluded": null
},
"minimumProductSpend": 1,
"minimumUnits": 1,
"maximumUnits": 1
}
]
}
},
"globalProductRestrictions": {
"enabled": true
},
"tenders": null,
"identityTypes": null
},
"reward": {
"basket": null,
"product": {
"banner1": {
"logicalOperator": "OR",
"collections": [
{
"products": {
"allRequired": false,
"included": {
"items": [
"12345",
"56789",
"45678",
"234567"
]
},
"excluded": null
},
"value": {
"interval": null,
"standard": {
"percentageAmount": null,
"allFree": false,
"discountAmount": 100,
"finalAmount": null
}
},
"maximumNumberOfUnits": 1,
"minimumNumberOfUnits": 1
}
]
}
}
},
"promoId": null
},
"version": 2,
"dateCreated": "2026-05-14T17:45:32+00:00",
"lastUpdated": "2026-05-14T19:33:44+00:00",
"lastUpdatedBy": 1
}When calling PUT /campaigns/{campaignId}, you must include all required non-scalar fields from the original campaign. Optional non-scalar fields may be added, updated, or removed by omitting them from the request body.
Updated about 19 hours ago
