Create Offering
This API creates an offering in the authenticated workspace. The offering is created directly in
active, scheduled, or expired state, determined by the scheduling dates. The API
validates the entire payload and returns all validation errors together in one response.
Requires the write:offers scope. Send an Idempotency-Key header to prevent duplicate
creation on retries.
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
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
Client-generated UUID v4. Reusing the same key within 24 hours returns the original 201 response without creating a new offering. A concurrent request that reuses an in-progress key returns 409 DUPLICATE_IDEMPOTENCY_KEY; reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT.
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.
Body
Configuration for creating a new offering. Required fields: request_id, name, priority, delivery, created_by, scheduling, segment_info, offer_content, and variation_meta.
Once the offering is active, the variation_meta type and variantsPerLocale key set are locked, so set the variation type and variant set carefully on the first call. Split percentages (SMV) and the control-group holdout stay editable while active.
Client-generated tracing ID for server-side log correlation. Format: the req_ prefix followed by a UUID v4. This is not the idempotency token — use the Idempotency-Key header to prevent duplicates.
^req_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"req_550e8400-e29b-41d4-a716-446655440000"
Display name of the offering, unique within the workspace. 5–100 characters. Allowed characters: letters, numbers, and underscores.
5 - 100^[a-zA-Z0-9_]+$"Summer_Sale_Promo_2026"
Priority value used to rank this offering during decisioning. Integer from 1 to 100.
1 <= x <= 10010
How the offering is delivered. scheduled — time-bound by the scheduling window. trigger — event-driven, with the scheduling window applied as a validity gate.
trigger, scheduled "scheduled"
Email address of the user creating the offering. Recorded in the audit log.
Scheduling window that bounds when an offering is eligible for delivery. Both
start_datetime and expiry_datetime are required. The offering status moves
automatically: scheduled before the start time, active between start and expiry,
expired after the expiry time.
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": {} }.
{
"filters": {
"included_filters": {
"filter_operator": "and",
"filters": [
{
"filter_type": "user_attributes",
"name": "country",
"operator": "equals",
"data_type": "string",
"value": "IN"
}
]
}
}
}
Content delivered to the user. Choose one of two formats:
- Flat format (single variant, single locale): send a
content_1object at the root. - Nested format (multiple variants or multiple locales): send a
localesmap. Each key is a locale identifier; within each locale, avariationsmap keys variation IDs (matching the names invariation_meta.variantsPerLocale) to their content.
Do not send both content_1 and locales in the same request.
{
"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 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, thetypeandvariantsPerLocalekey set are locked and returnIMMUTABLE_FIELD. ForSMVyou can still update thesmv_distributionsplit percentages andcontrol_group.percentage; forDMVonlycontrol_group.percentageis editable.
Variation strategies:
SMV(Static Multi-Variant): static allocation that you control. Variations are served according to the fixed percentagesmv_distributionsplit you define.DMV(Dynamic Multi-Variant): dynamic allocation that MoEngage optimizes automatically. You still provide ansmv_distributionsplit, but the system adjusts how variations are served.CONTROL_ONLY: control group only, with no content variations served.
{
"type": "SMV",
"variantsPerLocale": ["Variant_A", "Variant_B"],
"smv_distribution": {
"split": { "Variant_A": 70, "Variant_B": 30 }
},
"control_group": { "is_enabled": true, "percentage": 10 }
}
Free-text description of the offering. Maximum 500 characters.
500"20% discount for returning users who have not purchased in 30 days"
Tag IDs to attach to the offering. Each tag must already exist in the workspace; an unknown tag ID returns 400 INVALID_TAG_ID. Maximum 10 tags.
10["tag_summer_sale", "tag_returning_users"]
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.
{
"overall": {
"enabled": true,
"limit_value": 10000,
"limit_schedule": "DAILY"
},
"user_level": {
"enabled": true,
"limit_value": 3,
"limit_schedule": "WEEKLY"
}
}
When true, the offering honors the account-level Global Control Group (GCG): users in the GCG holdout do not receive it. Default false.
Impression tracking window in hours. After the offering is shown to a user, it is not shown again to that user within this window. Range 1–240.
1 <= x <= 24024
Custom attribute assignments used in Decision Policy scoring. Each entry references an offering attribute already configured in the workspace. Maximum 5 entries.
5Conversion 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 created. Check data.status — if start_datetime was in the past at the time of the request, the offering is created with status: expired and will not be served to users.