Update Benefit

Update an existing loyalty benefit.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Update Benefit

Updates a loyalty benefit, identified by its loyaltyBenefitId. Send the full benefit definition; the fields you send replace the stored values.

How the update behaves depends on the benefit's current status:

  • DRAFT benefit: the draft is updated in place and its version increments.
  • LIVE benefit: the update forks a new DRAFT version under the same loyaltyBenefitId, with version reset to 0. The forked draft keeps the parent's benefitIdentifier and loyaltyBenefitRecordId. The parent LIVE record stays live and unchanged, and gains a metadata.draftDetails object pointing to the in-progress draft. Submit and approve the draft through the workflow to publish your changes.

Once a draft fork exists, Get Benefit still returns the published LIVE version by default. Pass status=DRAFT to retrieve the in-progress draft fork instead.

Example request

curl -L -g -X PUT 'https://eu.api.capillarytech.com/v3/benefits/{{loyaltyBenefitId}}' \
-H 'Content-Type: application/json' \
-H 'Authorization: {{auth}}' \
-H 'X-CAP-API-AUTH-ORG-ID: {{orgId}}' \
-d '{
    "name": "Birthday bonus — updated",
    "description": "Extra points on birthday month",
    "programId": "2352",
    "expiryType": "CUSTOM",
    "startDate": "2026-08-01T00:00:00-06:00",
    "endDate": "2027-01-31T23:59:59-06:00",
    "timezoneName": "Asia/Kolkata",
    "tierIds": [
        8159,
        8165,
        8166,
        10545,
        10656
    ],
    "optin": {
        "optInStartDate": "2026-08-01T09:00:00-06:00",
        "optInEndDate": "2027-01-31T18:00:00-06:00"
    },
    "activities": [
        {
            "type": "SINGLE",
            "event": "TransactionAdd"
        }
    ]
}'

Prerequisites

  • Authentication: Basic auth or OAuth token with loyalty program management permissions.
  • The benefit must exist.
  • The tiers listed in tierIds must exist in the program.

Resource information

HTTP methodPUT
AuthenticationBasic or OAuth
Pagination supported?NO
Rate limitYES
Batch supportNO

Path parameters

FieldTypeRequiredDescription
loyaltyBenefitIdstringRequiredUnique ID of the benefit to update, returned by Create Benefit.

Body parameters

API Quick Reference

Benefit
├── name (string)
├── description (string)
├── programId (string)
├── expiryType (enum)
├── startDate (string)
├── endDate (string)
├── timezoneName (string)
├── tierIds[] (integer)
├── optin
│   ├── optInStartDate (string)
│   └── optInEndDate (string)
└── activities[]
    ├── type (enum)
    └── event (string)
FieldTypeRequiredDescription
namestringRequiredDisplay name of the benefit. Max 255 characters.
descriptionstringRequiredDescription of the benefit. Max 1000 characters.
programIdstringRequiredLoyalty program ID the benefit belongs to, passed as a string (for example, "973"). To retrieve the programId, use the Get Loyalty Programs API.
expiryTypeenumRequiredHow the benefit's validity ends. Case-sensitive. CUSTOM requires endDate. INDEFINITE sets a far-future end date automatically. Supported values: CUSTOM, INDEFINITE.
startDatestringRequiredDefines the benefit's start date and time in ISO 8601 format with the region offset.

For example: The start date is at 14:30:45 on December 16, 2025, in India

Format for the request parameter: 2025-12-16T14:30:45+05:30

Returned unchanged in the response, in the offset you send.
endDatestringConditionalDefines the benefit's end date and time in ISO 8601 format with the region offset.

For example: The end date is at 14:30:45 on December 16, 2025, in India

Format for the request parameter: 2025-12-16T14:30:45+05:30

Required when expiryType is CUSTOM. Omit it for INDEFINITE.
timezoneNamestringRequiredIANA time zone name for the benefit (for example, Asia/Kolkata). Use timezoneName (lowercase z) — this is the correct field name across Capillary APIs.
tierIdsarray (integer)RequiredTier IDs the benefit applies to. Each tier must exist in the program. Retrieve tier IDs with the List All Tiers API.
optinobjectOptionalObject containing the opt-in window during which customers can opt in to the benefit.
.optInStartDatestringOptionalDefines the opt-in window's start date and time in ISO 8601 format with the region offset.

For example: The start date is at 14:30:45 on December 16, 2025, in India

Format for the request parameter: 2025-12-16T14:30:45+05:30
.optInEndDatestringOptionalDefines the opt-in window's end date and time in ISO 8601 format with the region offset.

For example: The end date is at 14:30:45 on December 16, 2025, in India

Format for the request parameter: 2025-12-16T14:30:45+05:30
activitiesarray (object)RequiredActivities that the benefit applies to.
.typeenumRequiredActivity type. Case-sensitive. Supported values: SINGLE.
.eventstringRequiredEvent that triggers the activity (for example, TransactionAdd).

Example response

This example shows the response when you update a DRAFT benefit in place. The draft is updated under the same loyaltyBenefitId and its version increments. The benefit stays in DRAFT status, and benefitIdentifier and loyaltyBenefitRecordId stay null until it's approved. Updating a LIVE benefit instead returns a new DRAFT fork with version reset to 0 and the parent's benefitIdentifier and loyaltyBenefitRecordId retained.

{
  "data": {
    "loyaltyBenefitId": "86c29c3653f74c0a9f1b2c3d4e5f6a7b",
    "version": 1,
    "metadata": {
      "name": "Birthday bonus",
      "description": "Extra points on birthday month",
      "programId": "973",
      "orgId": 12345,
      "expiryType": "CUSTOM",
      "status": "DRAFT",
      "customerEligibilityType": null,
      "benefitIdentifier": null,
      "loyaltyBenefitRecordId": null,
      "startDate": "2026-08-01T00:00:00+05:30",
      "endDate": "2027-01-31T23:59:59+05:30",
      "timezoneName": "Asia/Kolkata",
      "createdOn": "2026-06-23T14:32:24+05:30",
      "lastModifiedOn": "2026-06-23T14:37:35+05:30",
      "createdBy": 123456,
      "lastModifiedBy": 123456,
      "draftDetails": null
    },
    "benefitCategoryId": -1,
    "tierIds": [8159, 8165],
    "optin": {
      "basedOn": null,
      "audienceMapping": null,
      "activities": null,
      "restrictions": null,
      "optInStartDate": "2026-08-01T09:00:00+05:30",
      "optInEndDate": "2027-01-31T18:00:00+05:30"
    },
    "activities": [
      {
        "type": "SINGLE",
        "event": "TransactionAdd",
        "allCycles": []
      }
    ],
    "limits": null,
    "configAttributes": null,
    "liabilityOwnerSplitInfo": null,
    "workflowMetadata": null,
    "communicationApprovalStatus": null,
    "parentId": null,
    "parentDetails": null,
    "comments": null,
    "id": "6a3a4ba0c1d2e3f4a5b6c7d8"
  },
  "errors": null,
  "warnings": null
}

Response parameters

FieldTypeDescription
dataobjectObject containing the updated benefit. For a LIVE benefit, this is the new DRAFT fork.
.loyaltyBenefitIdstringUnique ID of the benefit. The draft fork shares the same ID as the parent benefit.
.versionintegerVersion number of the benefit. Increments on an in-place draft update. Reset to 0 on a new draft fork of a LIVE benefit.
.metadataobjectObject containing the benefit's core attributes and audit details.
..namestringDisplay name of the benefit.
..descriptionstringDescription of the benefit.
..programIdstringLoyalty program ID the benefit belongs to.
..orgIdintegerOrg ID derived from the auth token.
..expiryTypeenumHow the benefit's validity ends. Possible values: CUSTOM, INDEFINITE.
..statusenumCurrent stage of the benefit lifecycle. DRAFT after a draft fork of a LIVE benefit. Possible values: DRAFT, PENDING_APPROVAL, LIVE, UPCOMING, PAUSED, STOPPED.
..customerEligibilityTypestringCustomer eligibility configuration. null unless advanced eligibility is set up.
..benefitIdentifierstringIdentifier carried over from the parent benefit on a draft fork. null while a benefit is in DRAFT or PENDING_APPROVAL and has never been approved.
..loyaltyBenefitRecordIdintegerRecord ID carried over from the parent benefit on a draft fork. null while a benefit is in DRAFT or PENDING_APPROVAL and has never been approved.
..startDatestringDate and time when the benefit starts, in ISO 8601 format. Returned in the offset you sent.
..endDatestringDate and time when the benefit ends, in ISO 8601 format. For INDEFINITE benefits, set to a far-future date automatically.
..timezoneNamestringIANA time zone name, as sent.
..createdOntimestampIndicates the date and time the benefit was created, in ISO 8601 format, returned in the server time zone.

EU server example: 2025-12-16T14:30:45Z → 16 December 2025, 14:30:45 (UTC)

India server example (real capture from this environment): 2026-06-23T14:32:24+05:30 → 23 June 2026, 14:32:24 (IST)

Note: The response time zone always matches the server time zone, regardless of the time zone offset in the request.
..lastModifiedOntimestampIndicates the date and time the benefit was last modified, in ISO 8601 format, returned in the server time zone.

EU server example: 2025-12-16T14:30:45Z → 16 December 2025, 14:30:45 (UTC)

India server example (real capture from this environment): 2026-06-23T14:37:35+05:30 → 23 June 2026, 14:37:35 (IST)

Note: The response time zone always matches the server time zone, regardless of the time zone offset in the request.
..createdByintegerTill ID of the person who created the benefit. Retrieve till IDs with the Get Active Tills API.
..lastModifiedByintegerTill ID of the person who last modified the benefit. Retrieve till IDs with the Get Active Tills API.
..draftDetailsobjectObject containing details of an in-progress draft when a LIVE benefit has an edit underway. Set on the parent LIVE record after an update; null on a DRAFT in-place update and on the draft fork itself.
.benefitCategoryIdintegerBenefit category ID. -1 means no benefit category is assigned.
.tierIdsarrayTier IDs the benefit applies to.
.optinobjectObject containing the opt-in window, as sent. null if no opt-in window was configured.
..basedOnstringOpt-in basis. null unless configured.
..audienceMappingobjectObject containing the opt-in's audience mapping. null unless configured.
..activitiesarrayActivities scoped to the opt-in. null unless configured.
..restrictionsobjectObject containing the opt-in's restrictions. null unless configured.
..optInStartDatestringDate and time when the opt-in window opens, in ISO 8601 format.
..optInEndDatestringDate and time when the opt-in window closes, in ISO 8601 format.
.activitiesarrayActivities the benefit applies to.
..typeenumActivity type. Possible values: SINGLE.
..eventstringEvent that triggers the activity.
..allCyclesarrayCycle entries computed for the activity.
.limitsarrayUsage limits configured for the benefit. null or empty unless limits are configured.
.configAttributesobjectObject containing advanced configuration attributes. null unless configured.
.liabilityOwnerSplitInfoarrayLiability split configuration entries. Each entry defines how liability for the benefit is split. null unless configured. See Get Benefit for entry fields.
.workflowMetadataobjectObject containing additional workflow data. null unless configured.
.communicationApprovalStatusobjectObject containing the communication approval result. null until the benefit is approved.
.parentIdstringID of the parent benefit, when this benefit is a draft fork of a LIVE benefit. null otherwise.
.parentDetailsobjectObject containing details of the parent benefit. null otherwise.
.commentsstringReviewer's note from the most recent workflow action. null until reviewed.
.idstringUnique ID of this benefit record. A draft fork has its own record ID, distinct from the parent.
errorsarrayError list. null on success.
warningsarrayWarning list. null on success.

Error & warning codes

CodeTypeDescription
loyaltyBenefitId=<id>ErrorNo benefit matches the given loyaltyBenefitId. HTTP 404.
LOYALTY_BENEFITS.NAME_REQUIREDErrorname is missing. HTTP 400.
LOYALTY_BENEFITS.DESCRIPTION_REQUIREDErrordescription is missing. HTTP 400.
LOYALTY_BENEFITS.PROGRAM_ID_REQUIREDErrorprogramId is missing. HTTP 400.
LOYALTY_BENEFITS.END_DATE_REQUIRED_FOR_CUSTOMErrorexpiryType is CUSTOM but endDate is missing. HTTP 400.
INVALID_EXPIRYTYPEErrorexpiryType is not INDEFINITE or CUSTOM. HTTP 400.
LOYALTY_BENEFITS.TIER_NOT_FOUNDErrorOne or more IDs in tierIds don't exist in the program. HTTP 400.

Note: Validation errors return a generic numeric code on the wire rather than an error-specific number. The Code column shows the stable symbolic code carried in the error message.


Path Params
string
required
Body Params
string
required
string
required
string
required
string
enum
required
Allowed:
string
required
string
string
required
tierIds
array of integers
required
tierIds*
optin
object
activities
array of objects
required
activities*
Headers
string
Responses

400

Validation error: see the error table in the doc page

401

Authentication failed

404

No benefit matches the given loyaltyBenefitId

Language
Credentials
Basic
base64
:
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json