trigger_condition, segmentation_details, scheduling_details, delivery_controls, conversion_goal_details, control_group_details, utm_params, campaign_audience_limit, advanced, and basic_details.geofences. Used by Create Campaign and Update Campaign.
For basic_details (excluding geofences) and campaign_content per channel, platform, and template type, see Campaign content reference.
The OpenAPI spec at
/api/campaigns/campaign-draft.yaml is the authoritative source for field types, enums, and required markers. This page adds runnable variants and conditional rules not expressible in inline schema descriptions.Quick start
The minimum audience configuration is eithersegmentation_details.is_all_user_campaign: true or a single filter under segmentation_details.included_filters. The minimum schedule is scheduling_details.delivery_type: ASAP. Event-triggered campaigns also require trigger_condition.
Page contents
| Section | Location in request body |
|---|---|
| Trigger conditions | trigger_condition |
| Filter primitives | included_filters.filters[], excluded_filters.filters[], trigger_condition.*_filters.filters[] |
| Campaign audience | segmentation_details |
| Campaign delivery schedule | scheduling_details |
| Delivery controls | delivery_controls |
| Conversion goal tracking | conversion_goal_details |
| Control groups | control_group_details |
| UTM parameters | utm_params |
| Campaign audience cap | campaign_audience_limit |
| Advanced Push settings | advanced (Push only) |
| Geofence targeting | basic_details.geofences |
| Validation rules | Cross-cutting rules enforced at validate or publish |
| Updating an existing campaign | Per-state restrictions for PATCH /v5/campaigns/{campaign_id} |
Trigger conditions
Thetrigger_condition object defines when a triggered campaign fires. It is required for the following delivery types:
- Push
EVENT_TRIGGERED,DEVICE_TRIGGERED, andLOCATION_TRIGGERED. - Email
EVENT_TRIGGERED.
BUSINESS_EVENT_TRIGGERED campaigns identify the trigger via basic_details.business_event and do not use trigger_condition.
| Field | Type | Channel support |
|---|---|---|
included_filters | FilterGroup | Push, Email. The primary condition that must match for the trigger to fire. |
secondary_included_filters | FilterGroup | Push, Email. Additional filters combined with the primary condition. |
trigger_delay_type | enum | Push: DELAY, ASAP, INTELLIGENT_DELAY. Email: DELAY, ASAP. |
trigger_delay_value | integer | The numeric delay value. Required when trigger_delay_type is DELAY. |
trigger_delay_granularity | enum | MINUTES, HOURS, or DAYS. Required when trigger_delay_type is DELAY. |
trigger_relation | enum | BEFORE or AFTER. Required when trigger_delay_type is DELAY. |
trigger_attr | object | The attribute used as the time anchor when trigger_relation is BEFORE. |
intelligent_delay_optimization | object | Push only. Required when trigger_delay_type is INTELLIGENT_DELAY. See Intelligent delay optimization (Push). |
Trigger delay variants
- ASAP
- DELAY (AFTER)
- DELAY (BEFORE)
- INTELLIGENT_DELAY (Push)
The campaign fires as soon as the trigger condition is met.
Intelligent delay optimization (Push)
Theintelligent_delay_optimization object defines the window within which MoEngage selects the optimal send time.
| Field | Type | Notes |
|---|---|---|
min_delay_value | integer | The numeric component of the lower bound. |
min_delay_granularity | enum | MINUTES or HOURS. |
max_delay_value | integer | The numeric component of the upper bound. |
max_delay_granularity | enum | HOURS or DAYS. |
Primary and secondary trigger filters
secondary_included_filters adds an extra filter group that must also match. Useful for triggers of the form “user did X and also Y”.
Trigger requirements per delivery type
| Delivery type | trigger_condition | basic_details.business_event | basic_details.geofences |
|---|---|---|---|
EVENT_TRIGGERED (Push, Email) | Required. | — | — |
BUSINESS_EVENT_TRIGGERED (Push, Email) | Not used. | Required. | — |
DEVICE_TRIGGERED (Push) | Required. | — | — |
LOCATION_TRIGGERED (Push) | Required. | — | Required. See Geofence targeting. |
ONE_TIME (Push, Email) | Not applicable. | — | — |
PERIODIC (Push, Email) | Not applicable. | — | — |
Filter primitives
Filters are the primitives used insideincluded_filters.filters[] and excluded_filters.filters[] on segmentation_details and inside included_filters.filters[] and secondary_included_filters.filters[] on trigger_condition. Every filter group has the shape:
filter_operator is and or or (lowercase). Filters are objects discriminated by filter_type:
filter_type | Purpose |
|---|---|
user_attributes | Match on a user attribute (string, double, datetime, bool). |
actions | Match on whether a user performed an event. |
custom_segments | Match users in a saved custom segment. |
- User attributes-based filters
- Action-based filters (with or without attributes)
- Custom segments
| Field | Type | Notes |
|---|---|---|
filter_type | enum | user_attributes (fixed). |
data_type | enum | string, double, datetime, or bool (lowercase). |
category | string | The attribute category (for example, Tracked Standard Attribute). |
name | string | The attribute name (for example, country, uid). |
operator | string | The operator depends on data_type. See Operators per data type. |
value | varies | The value to match. Not required for the exists operator. |
case_sensitive | boolean | Whether the comparison is case-sensitive. |
negate | boolean | Whether to negate the condition. |
project_name | string | Required when the Portfolio feature is enabled in the workspace. |
Operators per data type
data_type | Allowed operator values |
|---|---|
bool | is, exists |
double | in, between, lessThan, greaterThan, exists |
string | in, contains, containsInTheFollowing, startWithInTheFollowing, endsWithInTheFollowing, exists, is |
datetime | inTheLast, on, between, before, after, inTheNext, exists, today |
Campaign audience
Thesegmentation_details object defines who receives the campaign. Two top-level modes are supported: an explicit filter group, or a flag that targets all users.
| Field | Type | Notes |
|---|---|---|
included_filters | FilterGroup | Filters that include users in the audience. |
excluded_filters | FilterGroup | Filters that exclude users from the audience. |
is_all_user_campaign | boolean | When true, all users are targeted (subject to opt-in status). |
send_campaign_to_opt_out_users | boolean | When true, users who have opted out are also targeted. |
- All users
- Custom segment
- User attribute filter
- Included with excluded
- Include opt-outs
Campaign delivery schedule
Thescheduling_details.delivery_type field selects the send model. Different fields are required based on the value.
delivery_type | Send behavior | Required companion fields |
|---|---|---|
ASAP | As soon as the campaign is published. | None. |
AT_FIXED_TIME | At a specific timestamp. | start_time (ISO 8601). |
SEND_IN_BTS | At each user’s optimal time within a window. | start_time and bts_details. |
SEND_IN_USER_TIMEZONE | At a fixed wall-clock time in each user’s local timezone. | start_time and user_timezone_details. |
PERIODIC campaigns, delivery_type is AT_FIXED_TIME and periodic_details is required.
| Field | Type | Notes |
|---|---|---|
delivery_type | enum | ASAP, AT_FIXED_TIME, SEND_IN_BTS, or SEND_IN_USER_TIMEZONE. |
start_time | date-time (ISO 8601) | The campaign start time. |
expiry_time | date-time (ISO 8601) | The campaign expiry time. Used on triggered campaigns to bound activity. |
periodic_details | object | Required for PERIODIC campaigns. See Periodic schedules. |
bts_details | object | Required when delivery_type is SEND_IN_BTS. See Best Time to Send. |
user_timezone_details | object | Required when delivery_type is SEND_IN_USER_TIMEZONE. See User timezone. |
Schedule variants
- ASAP
- AT_FIXED_TIME
- SEND_IN_BTS
- SEND_IN_USER_TIMEZONE
- PERIODIC
Periodic schedules
Theperiodic_details object is required for PERIODIC campaigns.
| Field | Type | Notes |
|---|---|---|
sending_frequency | enum | DAILY, WEEKLY, or MONTHLY. |
repeat_frequency | integer | The repeat interval (for example, 1 for every week, 2 for every two weeks). |
no_of_occurences | integer | The total number of times the campaign sends. |
repeat_on_date_of_month | array of integer | Dates of the month to send on (1–31). Used with MONTHLY. |
repeat_on_days_of_week | array of enum | One or more of MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY. Used with WEEKLY or MONTHLY. |
repeat_on_days_of_week_for_month | array of { week_granularity, repeat_on_days_of_week } | Used with MONTHLY to target specific weeks of the month. |
repeat_on_days_of_week_for_month entries have the following shape:
| Field | Type | Notes |
|---|---|---|
week_granularity | enum | FIRST, SECOND, THIRD, FOURTH, or LAST. |
repeat_on_days_of_week | array of enum | One or more day names. |
- Daily
- Weekly
- Monthly on specific dates
- Monthly on first Monday
Best Time to Send
Thebts_details object is required when delivery_type is SEND_IN_BTS.
| Field | Type | Notes |
|---|---|---|
send_in_bts | boolean | Whether to send at the best time. |
if_user_bts_is_not_available | string | Fallback behavior when a user’s best time is unknown. |
if_user_bts_outside_time_window | string | Fallback behavior when a user’s best time falls outside the window. |
window_end_time | string | The end of the BTS window. |
User timezone
Theuser_timezone_details object is required when delivery_type is SEND_IN_USER_TIMEZONE.
| Field | Type | Notes |
|---|---|---|
send_in_user_timezone | boolean | Whether to send in each user’s local timezone. |
send_if_user_timezone_has_passed | boolean | Whether to still send to users whose local time has already passed start_time. |
Delivery controls
Thedelivery_controls object carries throttling, frequency capping, DND behavior, and offline/queueing flags. The accepted fields differ between Push and Email.
Push delivery controls
| Field | Type | Notes |
|---|---|---|
bypass_dnd | boolean | Whether to bypass Do Not Disturb. Required for event-triggered campaigns. |
campaign_throttle_rpm | integer | The throttle in requests per minute. Not applicable for device-triggered, location-triggered, and event-triggered campaigns. |
count_for_frequency_capping | boolean | Whether sends from this campaign count toward workspace frequency caps. |
ignore_frequency_capping | boolean | Whether this campaign bypasses workspace frequency caps. |
minimum_delay_between_two_notification_in_hour | integer | Minimum hours between two pushes from this campaign. Applies to event-triggered and device-triggered campaigns. |
max_time_to_show_message_of_same_camapign | string | Maximum hours the message is shown to a user. Applies to device-triggered campaigns. (Field name retains the spec typo camapign.) |
expiry_time_of_sync_data_in_hour | string | Hours after which synced campaign data expires if the trigger condition is not met. Applies to device-triggered campaigns. |
send_message_in_offline_mode | boolean | Whether to store and deliver the message while the device is offline. Applies to device-triggered campaigns. |
send_limit_value | string | Maximum times a user can receive the campaign within the window. Applies to location-triggered campaigns. |
send_limit_granularity_in_hours | string | The window in hours for send_limit_value. Applies to location-triggered campaigns. |
ignore_global_minimum_delay | boolean | Whether to bypass the workspace-wide minimum interval between pushes. Applies to event-triggered campaigns. |
queuing_enabled | boolean | Whether undeliverable messages are queued for later delivery. Flag-gated. Contact the MoEngage account team to enable. |
queue_duration | integer | The hours to keep messages queued. Must be greater than 0 when queuing_enabled is true. Flag-gated. |
- Throttle with frequency capping
- Event-triggered
- Device-triggered
- Location-triggered
- Queuing (flag-gated)
Email delivery controls
| Field | Type | Notes |
|---|---|---|
bypass_dnd | boolean | Whether to bypass Do Not Disturb. |
campaign_throttle_rpm | integer | The throttle in requests per minute. |
count_for_frequency_capping | boolean | Whether the campaign counts toward frequency caps. |
ignore_frequency_capping | boolean | Whether to bypass frequency capping. |
minimum_delay_between_two_notification_in_hour | integer | Minimum hours between two emails from this campaign. |
Conversion goal tracking
Theconversion_goal_details object configures the events MoEngage tracks to attribute campaign success.
| Field | Type | Notes |
|---|---|---|
attribution_window_in_hours | integer | The lookback window in hours for attributing goal events to the campaign. |
goals | array of Goal fields | The list of goals tracked. |
Goal fields
| Field | Type | Notes |
|---|---|---|
goal_name | string | The display name of the goal. |
goal_event_name | string | The event tracked as a conversion. |
goal_event_attribute | object | Optional. See Goal event attribute fields. |
is_primary_goal | boolean | Whether the goal is the primary goal. |
revenue_attribute | string | The event attribute used to track revenue. |
revenue_currency | string | The currency for revenue tracking. |
Goal event attribute fields
| Field | Type | Notes |
|---|---|---|
name | string | The attribute name. |
condition | string | The condition (for example, is, contains, between). |
data_type | enum | STRING, DOUBLE, BOOL, NUMBER, GEOPOINT, DATETIME, ARRAY_DOUBLE, ARRAY_STRING, OBJECT, or ARRAY_OBJECT. (Uppercase, differs from filter data_type.) |
value | string | The match value. |
value1 | string | A secondary value (used with between). |
negate | boolean | Whether to negate the condition. |
value_type | string | The type of value being filtered. |
array_filter_type | string | The logical filter type for array attributes. |
filters | array of object | Sub-filters used when data_type is OBJECT or ARRAY_OBJECT. |
is_case_sensitive | boolean | Whether the comparison is case-sensitive. |
- Single conversion goal
- Multiple conversion goals
Control groups
Thecontrol_group_details object configures the campaign-level and global control groups (users held back from the send).
| Field | Type | Notes |
|---|---|---|
is_campaign_control_group_enabled | boolean | Whether the campaign control group is enabled. |
campaign_control_group_percentage | integer (0–100) | The percentage of the audience held back. Required when is_campaign_control_group_enabled is true. |
is_global_control_group_enabled | boolean | Whether the workspace global control group applies to the campaign. |
- Campaign control group
- Global control group
UTM parameters
Theutm_params object appends UTM tracking parameters to URLs in the campaign content. The five standard keys are explicitly defined. Up to 5 additional custom keys prefixed with utm_ are also supported.
| Field | Type | Notes |
|---|---|---|
utm_source | string | The source of the traffic. Required when UTM parameters are used. |
utm_medium | string | The channel type. Required when UTM parameters are used. |
utm_campaign | string | The campaign name. |
utm_term | string | Search terms for paid traffic. |
utm_content | string | The content element that differentiates links. |
Custom utm_* keys | string | Up to 5 additional keys prefixed with utm_ (for example, utm_cust, utm_c1ust). |
Campaign audience cap
Thecampaign_audience_limit object caps the number of users a campaign can reach.
| Field | Type | Notes |
|---|---|---|
is_campaign_audience_limit_enabled | boolean | Whether the cap is enforced. When true, metric, frequency, and limit are all required. When false, those three fields must not be provided. |
metric | enum | SENT (the only value currently supported). Required when enabled. |
frequency | enum | TOTAL (lifetime cap, all delivery types on Push and Email) or INSTANCE (per-send cap, Periodic Push only). Required when enabled. |
limit | integer (1–9,999,999,999) | The maximum number of users. Required when enabled. |
BROADCAST_LIVE_ACTIVITY.
- Lifetime cap (TOTAL)
- Per-instance cap (INSTANCE)
- Disabled
Advanced Push settings
Theadvanced object (Push only) carries notification-expiration settings and per-platform priority.
advanced is part of the Push request body. It is not part of the Email request body.Expiration settings
| Field | Type | Notes |
|---|---|---|
expire_notification_after_value | integer | The numeric value for notification expiration. |
expire_notification_after_type | enum | HOUR or DAY. |
remove_from_inbox_after_value | integer | The numeric value for inbox removal. |
remove_from_inbox_after_type | enum | DAY (the only accepted value). |
Platform-level priority
| Field | Type | Notes |
|---|---|---|
android_specific_priority.send_with_priority | boolean | Whether to send with priority on Android. |
ios_specific_priority.apns_priority | enum | 1, 5, or 10 (strings). The APNS priority. |
ios_specific_priority.interruption_level | enum | Passive, Active, Time sensitive, or Critical. |
ios_specific_priority.relevance_score | number | 0, 0.5, or 1. |
- iOS APNS priority
- Android priority
Geofence targeting
Thebasic_details.geofences object is required for Push LOCATION_TRIGGERED campaigns. The field lives structurally inside basic_details and is documented here because it works in concert with trigger_condition and delivery_controls.send_limit_* for location-triggered targeting.
| Field | Type | Notes |
|---|---|---|
name | string | The unique name of the geofence. Required. |
latitude | string | The center latitude. Required. |
longitude | string | The center longitude. Required. |
radius | string | The radius in meters. Required. |
dwell_time_value | string | The numeric dwell time. Required when triggered_at is dwell. |
dwell_time_granularity | enum | MINUTES, HOURS, or DAYS. Required when triggered_at is dwell. |
response_time_value | string | The numeric response time before sending after the trigger condition is met. Required. |
response_time_granularity | enum | MINUTES, HOURS, or DAYS. Required. |
triggered_at | enum | ENTRY, EXIT, or dwell (note: dwell is lowercase). Required. |
- ENTRY
- EXIT
- dwell
The campaign fires when the user enters the geofence.
Validation rules
The following rules span multiple sub-objects on this page.| Rule | Source |
|---|---|
trigger_condition is required for Push EVENT_TRIGGERED, DEVICE_TRIGGERED, LOCATION_TRIGGERED, and Email EVENT_TRIGGERED. | PushTriggerCondition, EmailTriggerCondition descriptions |
basic_details.business_event is required for BUSINESS_EVENT_TRIGGERED (Push and Email). For BUSINESS_EVENT_TRIGGERED, trigger_condition is not used. | PushBasicDetailsV5.business_event, EmailBasicDetailsV5.business_event |
basic_details.geofences is required for LOCATION_TRIGGERED. LOCATION_TRIGGERED is Push only. | Geofence targeting |
geofences.triggered_at: dwell requires dwell_time_value and dwell_time_granularity. The value dwell is lowercase. ENTRY and EXIT are uppercase. | Geofences.triggered_at |
trigger_delay_type: DELAY requires trigger_delay_value, trigger_delay_granularity, and trigger_relation. | PushTriggerCondition.trigger_delay_type, EmailTriggerCondition.trigger_delay_type |
trigger_delay_type: INTELLIGENT_DELAY is Push only. Requires intelligent_delay_optimization (with min_delay_value, min_delay_granularity, max_delay_value, max_delay_granularity). min_delay_granularity accepts MINUTES or HOURS. max_delay_granularity accepts HOURS or DAYS. | PushTriggerCondition description |
trigger_relation: BEFORE requires trigger_attr.name (the time-attribute used as the anchor for the send). | PushTriggerCondition.trigger_relation |
filter_operator is lowercase, and or or. | FilterGroup.filter_operator |
UserAttributeFilter.data_type values are lowercase (string, double, datetime, bool). GoalEventAttribute.data_type values are uppercase (STRING, DOUBLE, …). The schemas are distinct. | UserAttributeFilter.data_type, GoalEventAttribute.data_type |
UserAttributeFilter.operator allowed values depend on data_type. Refer to Operators per data type. | UserAttributeFilter.operator |
UserAttributeFilter.project_name is required when the Portfolio feature is enabled in the workspace. | UserAttributeFilter.project_name |
For PERIODIC campaigns, scheduling_details.periodic_details is required, and scheduling_details.delivery_type is AT_FIXED_TIME. | PeriodicDetails description |
For SEND_IN_BTS, bts_details is required. For SEND_IN_USER_TIMEZONE, user_timezone_details is required. | BTSDetails, UserTimezoneDetails descriptions |
delivery_controls.bypass_dnd is required for Push event-triggered campaigns. | PushDeliveryControls.bypass_dnd |
delivery_controls.campaign_throttle_rpm is not applicable for Push device-triggered, location-triggered, and event-triggered campaigns. | PushDeliveryControls.campaign_throttle_rpm |
delivery_controls.queuing_enabled and queue_duration are flag-gated. queue_duration must be greater than 0 when queuing_enabled is true. | PushDeliveryControls.queuing_enabled |
delivery_controls.send_limit_value and send_limit_granularity_in_hours apply to location-triggered campaigns. | PushDeliveryControls.send_limit_value |
delivery_controls.max_time_to_show_message_of_same_camapign, expiry_time_of_sync_data_in_hour, and send_message_in_offline_mode apply to device-triggered campaigns. | PushDeliveryControls |
control_group_details.campaign_control_group_percentage is required when is_campaign_control_group_enabled is true. The percentage must be between 0 and 100. | ControlGroupDetails.campaign_control_group_percentage |
campaign_audience_limit is flag-gated. Including it on a workspace where the feature is not enabled returns a 400 VALIDATION_FAILED. When enabled, metric, frequency, and limit are all required. When disabled, those three fields must not be provided. frequency: INSTANCE is Periodic Push only. | CampaignAudienceLimit description |
utm_params accepts the 5 standard keys plus up to 5 additional utm_-prefixed custom keys. utm_source and utm_medium are required when UTM parameters are used. | UTMParams description |
advanced.expiration_settings.remove_from_inbox_after_type accepts only DAY. Other granularities fail. | AdvancedDetails.expiration_settings |
advanced.platform_level_priority.ios_specific_priority.apns_priority values are strings ("1", "5", "10"). relevance_score values are numbers (0, 0.5, 1). interruption_level accepts Passive, Active, Time sensitive, Critical (note the space and casing of Time sensitive). | AdvancedDetails.platform_level_priority |
Updating an existing campaign
PATCH /v5/campaigns/{campaign_id} reuses every schema on this page. Additional rules apply for updates.
- When a field inside a nested object is updated, the complete parent object must be included in the request. For example, to change a single filter in
segmentation_details.included_filters.filters, the fullsegmentation_detailsblock is included. - For campaigns in
ACTIVEstate, the following fields cannot be edited:trigger_conditionsegmentation_detailsconversion_goal_details- The scheduling type (
delivery_type) - The scheduling start date (
scheduling_details.start_time)
- For campaigns in
SCHEDULEDstate, all fields except the scheduling type can be edited. - Campaigns in
STOPPEDorARCHIVEDstate cannot be updated. - Updates to
trigger_conditionorcampaign_contenton event-triggered campaigns can take up to 30 minutes to propagate to users due to content caching. - For periodic campaigns, configuration changes apply from the next scheduled run.
- For one-time campaigns, changes apply to messages not yet dispatched at the time of the update.
- segmentation_details (Email)
- delivery_controls (Push)
- delivery_controls (Email)
- conversion_goal_details
- control_group_details
- campaign_audience_limit
- advanced (Push)
- basic_details.geofences
See also
- Campaign content reference —
basic_detailsandcampaign_contentper channel, platform, and template type. - Create Campaign — required fields, happy-path cURLs, error responses.
- Update Campaign — per-state edit restrictions, publish action.
- Update Campaign Status —
STOP,PAUSE,RESUMEtransitions. - Validate Campaign — pre-publish validation check.
- Campaign drafts overview — lifecycle, channels, supported delivery types.