Skip to main content
POST
/
v5
/
offers
curl --request POST \ --url https://api-{dc}.moengage.com/v5/offers \ --header 'Authorization: Basic <encoded-value>' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: <idempotency-key>' \ --data ' { "request_id": "req_550e8400-e29b-41d4-a716-446655440000", "name": "Summer_Sale_Promo_2026", "description": "20% off for returning users who have not purchased in 30 days", "priority": 10, "delivery": "scheduled", "created_by": "[email protected]", "tags": [ "tag_summer_sale", "tag_returning_users" ], "scheduling": { "start_datetime": "2026-07-01T00:00:00+05:30", "expiry_datetime": "2026-09-30T23:59:59+05:30", "timezone": "Asia/Kolkata" }, "segment_info": { "filters": {} }, "variation_meta": { "type": "SMV", "variantsPerLocale": [ "Variant_A" ], "smv_distribution": { "split": { "Variant_A": 100 } }, "control_group": { "is_enabled": false } }, "offer_content": { "locales": { "0": { "variations": { "Variant_A": { "content_1": { "type": "json", "value": "{\"headline\":\"Save 20% today\",\"cta_text\":\"Claim offer\",\"cta_url\":\"https://example.com/offer/summer\"}" } } } } } } } '
{ "response_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "type": "offer", "data": { "id": "offer_683abc123def456789012345", "status": "scheduled", "created_at": "2026-06-01T08:30:00Z" } }

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 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.

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.

Body

application/json

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.

request_id
string
required

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.

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_550e8400-e29b-41d4-a716-446655440000"

name
string
required

Display name of the offering, unique within the workspace. 5–100 characters. Allowed characters: letters, numbers, and underscores.

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

"Summer_Sale_Promo_2026"

priority
integer
required

Priority value used to rank this offering during decisioning. Integer from 1 to 100.

Required range: 1 <= x <= 100
Example:

10

delivery
enum<string>
required

How the offering is delivered. scheduled — time-bound by the scheduling window. trigger — event-driven, with the scheduling window applied as a validity gate.

Available options:
trigger,
scheduled
Example:

"scheduled"

created_by
string<email>
required

Email address of the user creating the offering. Recorded in the audit log.

scheduling
object
required

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.

segment_info
object
required

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
required

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
required

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 }
}
description
string

Free-text description of the offering. Maximum 500 characters.

Maximum string length: 500
Example:

"20% discount for returning users who have not purchased in 30 days"

tags
string[]

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.

Maximum array length: 10
Example:
["tag_summer_sale", "tag_returning_users"]
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
default:false

When true, the offering honors the account-level Global Control Group (GCG): users in the GCG holdout do not receive it. Default false.

imp_track_hours
integer

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.

Required range: 1 <= x <= 240
Example:

24

offering_attribute_configuration
object[]

Custom attribute assignments used in Decision Policy scoring. Each entry references an offering attribute already configured in the workspace. 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 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.

Response returned by POST /v5/offers on success.

response_id
string

Server-generated UUID for tracing this response.

Example:

"f47ac10b-58cc-4372-a567-0e02b2c3d479"

type
enum<string>

Resource type discriminator. Always offer.

Available options:
offer
data
object

Summary of the created offering.