Skip to main content
PATCH
/
v5
/
offers
/
{offer_id}
curl --request PATCH \
  --url https://api-{dc}.moengage.com/v5/offers/{offer_id} \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: <idempotency-key>' \
  --data '
{
  "request_id": "req_7b3f9200-c14a-42e8-b891-557766330002",
  "updated_by": "[email protected]",
  "scheduling": {
    "expiry_datetime": "2026-12-31T23:59:59+05:30"
  }
}
'
{
  "response_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "type": "offer",
  "data": {
    "id": "offer_683abc123def456789012345",
    "status": "active",
    "updated_at": "2026-06-16T11:00:00Z"
  }
}
Array fields are replaced entirely, not merged. tags and offering_attribute_configuration overwrite the existing values when included. To add one tag, send the current list plus the new tag ID. To remove all tags, send an empty array.

Rate Limit

The rate limits are at the workspace level. Each endpoint allows 100 requests per minute, 300 requests per hour, and 600 requests per day.

Authorizations

Authorization
string
header
required

Authentication is done via Basic Auth. This requires a base64-encoded string of your credentials in the format 'username:password'.

  • Username: Use your MoEngage Workspace ID (also known as the App ID). You can find it in the MoEngage dashboard at Settings > Account > APIs > Workspace ID (earlier app id).
  • Password: Use your API Key, which you can find within the Personalize tile.

For more information on authentication and getting your credentials, refer here.

Headers

Idempotency-Key
string<uuid>
required

Client-generated UUID v4. Reusing the same key within 24 hours returns the original 200 response without re-applying the update. A concurrent in-progress key returns 409 DUPLICATE_IDEMPOTENCY_KEY; reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT.

X-MOE-Request-Id
string<uuid>

Client-supplied trace ID (UUID v4). The server echoes it in the X-MOE-Request-Id response header so you can correlate the request with server-side logs.

Path Parameters

offer_id
string
required

Prefixed offering ID returned by the create endpoint, including the offer_ prefix.

Body

application/json

Only the fields you include are updated; omitted fields keep their current values.

Immutable and state-gated fields:

  • variation_meta is fully editable while the offering is scheduled. Once active, type and the variantsPerLocale key set are locked and return IMMUTABLE_FIELD; what stays editable depends on type — for SMV, the smv_distribution split percentages and control_group.percentage; for DMV, only control_group.percentage.
  • conversion can be updated only while the offering is scheduled.
  • scheduling.start_datetime can be changed only while the offering is scheduled. expiry_datetime can be updated in any modifiable state.
request_id
string
required

Client-generated tracing ID for server-side log correlation. Format: the req_ prefix followed by a UUID v4.

Pattern: ^req_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
Example:

"req_7b3f9200-c14a-42e8-b891-557766330002"

updated_by
string<email>
required

Email address of the user making the update. Always recorded in the audit log.

name
string

New display name, unique within the workspace. 5–100 characters. Allowed characters: letters, numbers, and underscores.

Required string length: 5 - 100
Pattern: ^[a-zA-Z0-9_]+$
description
string

New free-text description. Maximum 500 characters.

Maximum string length: 500
priority
integer

New priority value used to rank this offering. Integer from 1 to 100.

Required range: 1 <= x <= 100
tags
string[]

Replacement tag list. This overwrites the existing tags entirely rather than adding to them. To add one tag, send the current tags plus the new one; to remove all tags, send an empty array. Each tag ID must already exist. Maximum 10 tags.

Maximum array length: 10
scheduling
object

Partial scheduling update. All fields are optional. start_datetime can be changed only while the offering is scheduled. expiry_datetime can be updated in any modifiable state to extend or shorten the window.

segment_info
object

Audience targeting that controls which users are eligible for the offering. The filter structure is forwarded as-is to the MoEngage segmentation service. Use included_filters for criteria a user must match and excluded_filters for criteria that disqualify a user. To target all users, send an empty filters object: { "filters": {} }.

Example:
{
"filters": {
"included_filters": {
"filter_operator": "and",
"filters": [
{
"filter_type": "user_attributes",
"name": "country",
"operator": "equals",
"data_type": "string",
"value": "IN"
}
]
}
}
}
offer_content
object

Content delivered to the user. Choose one of two formats:

  • Flat format (single variant, single locale): send a content_1 object at the root.
  • Nested format (multiple variants or multiple locales): send a locales map. Each key is a locale identifier; within each locale, a variations map keys variation IDs (matching the names in variation_meta.variantsPerLocale) to their content.

Do not send both content_1 and locales in the same request.

Example:
{
"content_1": {
"type": "json",
"value": "{\"headline\":\"Save 20% today\",\"cta_text\":\"Claim offer\",\"image_url\":\"https://cdn.example.com/banner.png\",\"cta_url\":\"https://example.com/offer/summer\"}"
}
}
variation_meta
object

Variation configuration for the offering. Editability depends on the offering's status and variation type:

  • While the offering is scheduled, the entire object is editable.
  • Once active, the type and variantsPerLocale key set are locked and return IMMUTABLE_FIELD. For SMV you can still update the smv_distribution split percentages and control_group.percentage; for DMV only control_group.percentage is editable.

Variation strategies:

  • SMV (Static Multi-Variant): static allocation that you control. Variations are served according to the fixed percentage smv_distribution split you define.
  • DMV (Dynamic Multi-Variant): dynamic allocation that MoEngage optimizes automatically. You still provide an smv_distribution split, but the system adjusts how variations are served.
  • CONTROL_ONLY: control group only, with no content variations served.
Example:
{
"type": "SMV",
"variantsPerLocale": ["Variant_A", "Variant_B"],
"smv_distribution": {
"split": { "Variant_A": 70, "Variant_B": 30 }
},
"control_group": { "is_enabled": true, "percentage": 10 }
}
capping_rules
object

Frequency capping that limits how often the offering is delivered. Two independent rules can be enabled at the same time:

  • overall — caps total deliveries across all users within the schedule period.
  • user_level — caps deliveries to a single user within the schedule period.
Example:
{
"overall": {
"enabled": true,
"limit_value": 10000,
"limit_schedule": "DAILY"
},
"user_level": {
"enabled": true,
"limit_value": 3,
"limit_schedule": "WEEKLY"
}
}
is_global_control_enabled
boolean

Toggle the account-level Global Control Group holdout for this offering.

imp_track_hours
integer

New impression tracking window in hours. Range 1–240.

Required range: 1 <= x <= 240
offering_attribute_configuration
object[]

Replacement custom attribute configuration. This overwrites the existing list entirely. Maximum 5 entries.

Maximum array length: 5
conversion
object

Conversion goal configuration used to measure offering effectiveness. You can set or change conversion only while the offering is scheduled; on an active offering it returns 400 IMMUTABLE_FIELD.

Response

Offering updated.

Response returned by PATCH /v5/offers/{offer_id} on success.

response_id
string

Server-generated UUID for tracing this response.

Example:

"a1b2c3d4-e5f6-7890-abcd-ef1234567890"

type
enum<string>

Resource type discriminator. Always offer.

Available options:
offer
data
object

Summary of the updated offering.