Idempotency-Key (UUID v4) on all POST and PATCH requests to ensure safe retries. The X-MOE-Tenant-ID header (your Workspace ID) is optional — when omitted, the workspace is resolved from the Basic Auth credentials in the Authorization header.
Supported channels and delivery types
Channel support varies by operation:| Operation | Supported channels |
|---|---|
| Create Campaign, Update Campaign, Validate Campaign | EMAIL, PUSH (Android, iOS, Web) |
| Get Campaign, Search Campaigns, Get Campaign Meta | EMAIL, PUSH, SMS, WHATSAPP, FACEBOOK, GOOGLE ADS, CONNECTORS |
| Test Campaign | EMAIL, PUSH |
| Personalized Preview | EMAIL, PUSH, SMS |
ONE_TIMEPERIODICEVENT_TRIGGEREDBUSINESS_EVENT_TRIGGEREDDEVICE_TRIGGERED(Push only)LOCATION_TRIGGERED(Push only)BROADCAST_LIVE_ACTIVITY(Push iOS only)
Campaign lifecycle
Create
channel, campaign_delivery_type, and created_by. Add content, audience, and scheduling incrementally across subsequent update calls.Update
Validate (optional)
Test
channel and campaign_content directly in the request without saving a draft, and draft mode, where you pass a draft_id to load content from a saved draft. Draft mode is new in V5.Publish
ACTIVE by sending { "status": "PUBLISH" } in a PATCH /v5/campaigns/{campaign_id} request. There is no separate publish endpoint. Publishing is a status transition sent through the Update Campaign endpoint.- Draft state: Campaigns now start as drafts, giving you full control over when to go live. Publish explicitly using
PATCH /v5/campaigns/{campaign_id}with{ "status": "PUBLISH" }. - Validate endpoint: V5 adds a dedicated validate step to check your campaign before publishing. There is no equivalent in V1.
- Updated authentication header: The
MOE-APPKEYheader is replaced byX-MOE-Tenant-IDfor passing your Workspace ID.
Campaign versioning
Campaign Versioning is opt-in per workspace. When it is turned on, publishing changes to a campaign that is already live creates a new campaign document with an incrementedversion_number. The campaign_id returned in API responses is the canonical identifier: it stays the same across versions so you can correlate drafts, search results, and analytics. Each version still has its own raw id (24-character ObjectId).
For UI-focused behavior and version history in the dashboard, see Campaign versioning.
Endpoints
The Campaigns API consists of the following endpoints to manage your campaign lifecycle:- Create Campaign: Initializes a new Push or Email campaign in a
DRAFTstate using minimal required fields. - Get Campaign: Retrieves a single campaign in its full deparsed form, displaying its current state and configuration.
- Update Campaign: Updates specific components of an existing draft or triggers the formal
PUBLISHaction to launch the campaign. - Validate Campaign: Safely runs a full publish-time validation check without modifying the draft or changing its state.
- Update Campaign Status: Applies lifecycle transitions (STOP, PAUSE, RESUME) to campaigns that have already been published.
- Search Campaigns: Searches for campaigns using granular filters, with the ability to explicitly include or exclude campaigns in draft state.
- Get Campaign Meta: Fetches lightweight metadata, including daily cached reachability estimates for scheduled campaigns.
- Test Campaign: Sends a test push or email to up to 10 users. Supports inline mode (pass
channelandcampaign_contentdirectly) and draft mode (passdraft_idto load content from a saved draft). Draft mode is new in V5. - Personalized Preview: Returns a resolved preview of personalized campaign content for a specific user without sending a message.
FAQs
Create Campaign
What fields are required to create a campaign?
What fields are required to create a campaign?
channel (PUSH or EMAIL), campaign_delivery_type, and created_by (the email of the user creating the campaign). All other components, including content, audience, scheduling, and delivery controls, are optional and can be added later using the Update Campaign endpoint.Can I include full campaign content when creating a campaign, or must I build it progressively?
Can I include full campaign content when creating a campaign, or must I build it progressively?
DRAFT_CREATE validation standards.How does the request_id prevent duplicate campaign creation?
How does the request_id prevent duplicate campaign creation?
request_id is an idempotency key scoped to campaign creation. For Push campaigns, the same request_id cannot be reused for one hour after a successful creation. For Email campaigns, the window is one day. If a creation attempt fails, you can retry immediately using the same request_id.What delivery types are supported for Push and Email campaigns?
What delivery types are supported for Push and Email campaigns?
- Push:
ONE_TIME,PERIODIC,EVENT_TRIGGERED,BUSINESS_EVENT_TRIGGERED,DEVICE_TRIGGERED,LOCATION_TRIGGERED,BROADCAST_LIVE_ACTIVITY - Email:
ONE_TIME,PERIODIC,EVENT_TRIGGERED,BUSINESS_EVENT_TRIGGERED
What are the creation rate limits?
What are the creation rate limits?
- Request rate: 5 per second, 25 per minute, 100 per hour.
- Campaign creation: 5 successful per minute, 25 per hour, 100 per day.
How do I personalize campaign content using user attributes?
How do I personalize campaign content using user attributes?
title, message, subject, and html_content. Use the following syntax to reference a user attribute at delivery time:How do campaigns created via the API appear in the MoEngage dashboard?
How do campaigns created via the API appear in the MoEngage dashboard?
DRAFT status can be updated via subsequent API calls.Can I pass both custom_template_id and html_content in the same Email campaign request?
Can I pass both custom_template_id and html_content in the same Email campaign request?
custom_template_id and html_content are mutually exclusive in the Email campaign content payload. Submitting both fields in the same request returns a validation error. Use custom_template_id to reference a saved template from the MoEngage Email Template library, or use html_content to supply raw HTML directly.How do I target a custom segment when creating a campaign?
How do I target a custom segment when creating a campaign?
segmentation_details.included_filters using filter_type: custom_segments. You can find the segment ID and name in the MoEngage dashboard under Segments.excluded_filters. You can combine multiple filter types, such as user attributes, actions, and custom segments, in the same filters array using the filter_operator (and / or).Get Campaign
What identifier do I use to fetch a campaign?
What identifier do I use to fetch a campaign?
campaign_id path parameter, which is the 24-character ObjectId returned when you create or search for a campaign. Pass it in the GET /v5/campaigns/{campaign_id} request.What is the difference between campaign_id and id in the response?
What is the difference between campaign_id and id in the response?
campaign_id is the stable canonical identifier that stays the same across all versions of a campaign. The id field is the raw ObjectId unique to each individual version document. Use campaign_id to correlate drafts, published campaigns, and analytics across versions.What campaign statuses can be returned by this endpoint?
What campaign statuses can be returned by this endpoint?
DRAFT, SCHEDULED, ACTIVE, SENDING, PAUSED, SENT, STOPPED, or ARCHIVED.Update Campaign
Can I update campaign components and publish in the same request?
Can I update campaign components and publish in the same request?
status key. To publish, send only { "status": "PUBLISH" }. Combining both in a single request returns a 400 Bad Request error.Which fields cannot be edited once a campaign is Active?
Which fields cannot be edited once a campaign is Active?
- Active: You cannot edit
trigger_condition,segmentation_details,conversion_goal_details, the scheduling type, or the scheduling start date. - Scheduled: All fields can be edited except the scheduling type.
- Stopped / Archived: No fields can be updated.
How long does it take for updated content to reach users in Event-triggered campaigns?
How long does it take for updated content to reach users in Event-triggered campaigns?
Do I need to send the full campaign payload when updating?
Do I need to send the full campaign payload when updating?
campaign_content object in the request body.What API scopes are required to update or publish a campaign?
What API scopes are required to update or publish a campaign?
campaigns:create_manage scope. Publishing a campaign (sending { "status": "PUBLISH" }) requires the campaigns:create_manage_publish scope.Is there a separate publish endpoint?
Is there a separate publish endpoint?
{ "status": "PUBLISH" } as the request body in a PATCH /v5/campaigns/{campaign_id} request. The Update Campaign Status endpoint (POST /v5/campaigns/{campaign_id}/status) is a different endpoint that handles post-publish transitions, STOP, PAUSE, and RESUME, and does not accept PUBLISH.Can I update the segmentation audience when the campaign is Active?
Can I update the segmentation audience when the campaign is Active?
segmentation_details field cannot be updated for campaigns in ACTIVE state. To change the audience, stop the campaign and create a new one. See Which fields cannot be edited once a campaign is Active? for the full list of non-editable fields by campaign state.When does updated content reach users?
When does updated content reach users?
- Event-triggered campaigns: Updated content is cached and can take up to 30 minutes to propagate to users after a successful update.
- Periodic campaigns: The updated configuration applies from the next scheduled run.
- One-time campaigns: Changes apply to any messages that have not yet been dispatched at the time of the update.
How do I find the campaign ID to use in the update request?
How do I find the campaign ID to use in the update request?
campaign_id is returned in the data.id field of the Create Campaign response. You can also retrieve it using GET /v5/campaigns/{campaign_id} or by using the Search Campaigns endpoint to look up campaigns by name, status, channel, or delivery type.Can I change the template type in an Active Push campaign?
Can I change the template type in an Active Push campaign?
template_type field is part of campaign_content, which can be updated for campaigns in ACTIVE state. If you change the template type, include all required fields for the new template in the same request, as each template type has different required fields.Can I add or remove platforms in an Active Push campaign?
Can I add or remove platforms in an Active Push campaign?
platforms field in basic_details is not restricted for ACTIVE campaigns. Adding a platform extends delivery to that platform for future sends; removing a platform stops delivery to it.Validate Campaign
Does calling validate change the campaign's state or content?
Does calling validate change the campaign's state or content?
DRAFT_PUBLISH) without modifying the campaign or changing its status.What HTTP status code does this endpoint return if the campaign is invalid?
What HTTP status code does this endpoint return if the campaign is invalid?
200. Whether the campaign is valid or not is indicated in the response body through the valid field (true or false) and an errors array that lists any validation failures.Is an idempotency key required for this endpoint?
Is an idempotency key required for this endpoint?
Idempotency-Key header.Update Campaign Status
What status transitions does this endpoint support?
What status transitions does this endpoint support?
| Action | Supported delivery types | Valid source states |
|---|---|---|
STOP | ONE_TIME | ACTIVE, SCHEDULED, PAUSED, SENDING |
PAUSE | PERIODIC, EVENT_TRIGGERED | ACTIVE, SCHEDULED, SENDING |
RESUME | PERIODIC, EVENT_TRIGGERED | PAUSED |
Can I use this endpoint to publish a campaign?
Can I use this endpoint to publish a campaign?
PATCH /v5/campaigns/{campaign_id} with the body { "status": "PUBLISH" }.Can I stop a Periodic or Event-triggered campaign?
Can I stop a Periodic or Event-triggered campaign?
STOP is not valid for Periodic or Event-triggered campaigns. Use PAUSE to temporarily halt a running Periodic or Event-triggered campaign and RESUME to restart it. Attempting to STOP a Periodic campaign returns a 422 Unprocessable Entity error.Can I stop a One-time campaign that is in SENDING state?
Can I stop a One-time campaign that is in SENDING state?
STOP is valid for One-time campaigns in SCHEDULED, ACTIVE, PAUSED, and SENDING states. If the campaign is in SENDING state, the action halts any remaining sends. Messages already dispatched before the stop is processed are still delivered.Which campaign types and channels does this endpoint support?
Which campaign types and channels does this endpoint support?
- Push: Periodic, Event-triggered, Device-triggered, and Location-triggered campaigns.
- Email: Periodic and Event-triggered campaigns.
- Both channels: Stopping a Scheduled One-time campaign.
Search Campaigns
Are campaigns in draft state included in search results by default?
Are campaigns in draft state included in search results by default?
DRAFT state are excluded from results unless you explicitly include DRAFT in the campaign_fields.status array. This preserves backward compatibility with existing integrations that do not expect draft rows in results.What is the maximum number of campaigns returned per page?
What is the maximum number of campaigns returned per page?
limit and page parameters to paginate through results.How do I identify which campaign belongs to a flow?
How do I identify which campaign belongs to a flow?
flow_name and flow_id fields in the response. If these fields are present, the campaign is a node within a flow.How does campaign versioning affect search results?
How does campaign versioning affect search results?
campaign_id. You can filter by version_number in the campaign_fields object to narrow results to a specific version.How do I search for SMS campaigns?
How do I search for SMS campaigns?
"SMS" in the campaign_fields.channels array. Matching results return channel: SMS and include SMS-specific fields, connector (connector type and name) and sender_name, in each campaign object. Note that SMS campaign creation and update are not supported in V5; this endpoint retrieves existing SMS campaigns only.How do I retrieve campaigns that are part of a flow?
How do I retrieve campaigns that are part of a flow?
include_child_campaigns: true in the request body. Flow-node campaigns are excluded from results by default. When this flag is enabled, flow-node campaigns appear in the results with flow_id and flow_name populated. Periodic child campaigns also appear with a parent_id field when this flag is set.How do I include archived campaigns in search results?
How do I include archived campaigns in search results?
include_archive_campaigns: true in the request body. Archived campaigns are excluded by default, regardless of whether ARCHIVED is listed in campaign_fields.status. You must set this flag to true to include them.Can I filter SMS campaigns by sender name?
Can I filter SMS campaigns by sender name?
sender_name filter in the search request. To find SMS campaigns from a specific sender, pass "SMS" in campaign_fields.channels to retrieve all SMS campaigns, then filter by the sender_name field returned in each result on the client side.Get Campaign Meta
Is reachability information available for all campaign types?
Is reachability information available for all campaign types?
Can reachability be refreshed with every API call?
Can reachability be refreshed with every API call?
What channels does this endpoint support?
What channels does this endpoint support?
Where does the rejection_comment field appear?
Where does the rejection_comment field appear?
rejection_comment field appears in the meta response while the campaign remains in DRAFT status.Test Campaign
Can I send a test without first saving a campaign?
Can I send a test without first saving a campaign?
channel and campaign_content directly in the test request. The content is not stored on the server. For Email inline tests, also include the connector object. To test using a saved campaign, use draft mode and pass the draft_id instead.What is the maximum number of recipients for a test send?
What is the maximum number of recipients for a test send?
identifier_values array.Can I test a campaign for a specific platform, locale, or variation?
Can I test a campaign for a specific platform, locale, or variation?
test_campaign_meta.platform (ANDROID, IOS, or WEB), locale_name, or variation in the request.Can I send a test to a recipient who is not a MoEngage user?
Can I send a test to a recipient who is not a MoEngage user?
EMAIL as the identifier type and provide the recipient’s email address. The test will be sent, but the content will not be personalized with user profile data since there is no matching user record in MoEngage.Push Campaigns
How do I find the template ID for a Push notification template?
How do I find the template ID for a Push notification template?
template_id for each template. Pass this value as custom_template_id in the campaign_content payload when creating or updating a Push campaign.How do I know which fields are required for a specific Push template type?
How do I know which fields are required for a specific Push template type?
template_type. Set the template_type in the basic_details object of your campaign content payload. The supported values for Android are BASIC, STYLIZED_BASIC, SIMPLE_IMAGE_CAROUSEL, IMAGE_BANNER_WITH_TEXT, TIMER, TIMER_WITH_PROGRESS_BAR, and Custom. For iOS, the supported values are BASIC, STYLIZED_BASIC, SIMPLE_IMAGE_CAROUSEL, and Custom.For the Custom template type, custom_template_id is required. For all other types, refer to the campaign_content schema in the Create Campaign reference for the full list of required and optional fields per template type.SMS Campaigns
Can I create or update SMS campaigns using V5?
Can I create or update SMS campaigns using V5?
How do I identify the sender name for an SMS campaign?
How do I identify the sender name for an SMS campaign?
sender_name field in the campaign response carries the sender name configured for the campaign. This field is only populated for SMS campaigns. There is no sender_name filter in the Search Campaigns request. To find campaigns for a specific sender, retrieve all SMS campaigns and filter by sender_name on the client side.How do I retrieve the connector configuration for an SMS campaign?
How do I retrieve the connector configuration for an SMS campaign?
connector object in the campaign response contains the connector_type and connector_name for the campaign. For SMS campaigns, these fields identify the SMS delivery provider configured in your workspace.Personalized Preview
What channels does the Personalized Preview endpoint support?
What channels does the Personalized Preview endpoint support?
PUSH, EMAIL, and SMS. Pass the target channel in the channel field of the request body.Does this endpoint send a message to the user?
Does this endpoint send a message to the user?
What personalization sources does this endpoint resolve?
What personalization sources does this endpoint resolve?
How do I preview content for an event-triggered campaign?
How do I preview content for an event-triggered campaign?
event_attributes object. The endpoint injects these values at resolution time to simulate how the content would render for a specific event. For example:{{ event.product_name }}.How do I preview content that uses a custom template?
How do I preview content that uses a custom template?
custom_template_id in the campaign_content object, the same way you would in a Create Campaign request. The endpoint fetches and resolves the template, then returns the fully rendered output for the specified user.Can I use a saved draft with the Personalized Preview endpoint?
Can I use a saved draft with the Personalized Preview endpoint?
campaign_content. It does not load content from a saved draft. To send a test message from a saved draft, use the Test Campaign endpoint with draft_id.