Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/moengage-update-campaigns-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no email required.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Moengage Update Campaigns API
version: '2025-11-20'
contact:
name: MoEngage Developer Team
email: support@moengage.com
url: https://developers.moengage.com
description: 'Operations tagged Update Campaigns across 2 of this provider''s published API definitions: moengage-campaign-draft-openapi.yml, moengage-campaigns-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api-{dc}.moengage.com/
description: MoEngage Campaigns API Server
variables:
dc:
default: '01'
description: Data center (DC) segment in the hostname. Replace `OX` with your workspace DC (01–06 or 101). See [Data centers](/api/introduction#data-centers).
- url: https://api-{dc}.moengage.com/core-services/v1
description: MoEngage Campaigns API Server
variables:
dc:
default: '01'
description: The ‘dc’ in the API Endpoint URL refers to the MoEngage Data Center (DC). MoEngage hosts each customer in a different DC. You can find your DC number and replace the value of ‘dc’ in the URL by referring to the DC and API endpoint mapping [here](/api/introduction#data-centers). Your MoEngage Data Center (DC) can be 01, 02, 03, 04, 05, 06, or 101.
security:
- BasicAuth: []
tags:
- name: Update Campaigns
paths:
/v5/campaigns/{campaign_id}:
patch:
operationId: patch_draft_campaign_v5
summary: Update Campaign (V5)
description: 'Updates individual components of a campaign draft.
'
x-mint:
content: '<Note>
**Campaign publishing is not yet available in V5.** This endpoint only supports updating draft components. To publish campaigns, use the V1 API at `PATCH /core-services/v1/campaigns/{campaign_id}` in the interim. Publishing via V5 will be available in a future release.
</Note>
Send a `PATCH` request without a `status` key in the body.
The API merges each submitted component into the existing draft, then validates the full merged state (`DRAFT_PATCH`).
After all individual components pass validation, cross-component checks run on the combined result.
Only the fields you include in the request body are updated. Fields you omit retain their current values.
For the full field reference per delivery type, see the [Create Campaign API](/api/campaigns/create-campaign).
#### Update restrictions by campaign state
| Campaign state | Editable fields | Non-editable fields |
| :--- | :--- | :--- |
| **DRAFT** | All fields | — |
| **SCHEDULED:** One-time (no instance sent) | All fields | `scheduling_type` |
| **SCHEDULED:** Periodic or Event-triggered (no instance sent) | All fields | `scheduling_type` |
| **ACTIVE** | All fields except those listed as non-editable | `trigger_condition`, `segmentation_details`, `conversion_goal_details`, `scheduling_type`, `scheduling_start_date` |
| **STOPPED** or **ARCHIVED** | — | All fields (no updates allowed) |
<Note>
For **Event-triggered campaigns**, updated content is cached and takes up to 30 minutes to take effect.
</Note>
#### Rate Limits
| Rate Limit Name | Rate Limit |
| :--- | :--- |
| Update campaign per second | The total number of update campaign requests per second per client allowed is 10. |
| Update campaign per minute | The total number of update campaign requests per minute per client allowed is 100. |
| Update campaign per hour | The total number of update campaign requests per hour per client allowed is 6000. |
<Note>
**Notes**
* Breaching the limits will reject the request.
* Per-hour and per-day limits use a rolling window of the last 1 hour and last 24 hours respectively.
</Note>
'
tags:
- Update Campaigns
parameters:
- $ref: '#/components/parameters/MOE-APPKEY'
- $ref: '#/components/parameters/X-MOE-Request-Id'
- name: campaign_id
in: path
required: true
description: 'The unique ID of the campaign to update.
You can fetch the campaign ID using the [Get Campaign Details API](/api/get-campaign-details/search-campaigns-v5) by filtering with campaign name, channel, or other criteria.
'
schema:
type: string
- $ref: '#/components/parameters/Idempotency-Key-Required'
- $ref: '#/components/parameters/X-MOE-Scopes'
requestBody:
description: 'In this payload, you can include the fields you want to update.
**Notes:** - Pass only the fields you want to update. You don''t need to send the complete payload.
- If updating a field within an object, you must pass the complete object.
- If updating a nested field, you must pass the complete parent object.
For example, to update the title of a Push notification, pass the complete campaign_content object.
- Use the tabs below to select your campaign type. The schema will adapt based on the selected channel.
'
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignPatchV5Request'
examples:
push_update_campaign_content:
summary: Push - Update campaign_content
value:
request_id: '{{request_id}}'
channel: PUSH
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
campaign_content:
content:
push:
android:
template_type: BASIC
basic_details:
title: '{{notification_title}}'
message: '{{notification_message}}'
email_update_campaign_content:
summary: Email - Update campaign_content
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
campaign_content:
content:
email:
subject: '{{email_subject}}'
sender_name: '{{sender_name}}'
from_address: '{{from_email}}'
html_content: '{{html_body}}'
email_editor: Froala Editor
push_update_basic_details:
summary: Push - Update basic_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
basic_details:
name: '{{campaign_name}}'
platforms:
- ANDROID
- IOS
tags:
- '{{tag}}'
team: '{{team_name}}'
push_update_segmentation_details:
summary: Push - Update segmentation_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
segmentation_details:
included_filters:
filter_operator: and
filters:
- filter_type: actions
action_name: '{{event_name}}'
execution:
type: atleast
count: 1
executed: true
push_update_scheduling_details:
summary: Push - Update scheduling_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
scheduling_details:
delivery_type: AT_FIXED_TIME
start_time: '{{start_time}}'
expiry_time: '{{expiry_time}}'
push_update_trigger_condition:
summary: Push - Update trigger_condition
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
trigger_condition:
included_filters:
filter_operator: and
filters:
- filter_type: actions
action_name: '{{trigger_event_name}}'
execution:
type: atleast
count: 1
executed: true
trigger_delay_type: DELAY
trigger_delay_value: 30
trigger_delay_granularity: MINUTES
trigger_relation: AFTER
push_update_delivery_controls:
summary: Push - Update delivery_controls
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
delivery_controls:
bypass_dnd: false
send_limit_value: '{{max_sends_per_user}}'
send_limit_granularity_in_hours: '{{send_limit_window_hours}}'
push_update_utm_params:
summary: Push - Update utm_params
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
utm_params:
utm_source: '{{utm_source}}'
utm_medium: push
utm_campaign: '{{utm_campaign}}'
push_update_campaign_audience_limit:
summary: Push - Update campaign_audience_limit (PERIODIC or EVENT_TRIGGERED)
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
campaign_audience_limit:
is_campaign_audience_limit_enabled: true
metric: SENT
frequency: TOTAL
limit: 100000
push_update_conversion_goal_details:
summary: Push - Update conversion_goal_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
conversion_goal_details:
attribution_window_in_hours: 36
goals:
- goal_name: Goal 1
goal_event_name: '{{conversion_event_name}}'
is_primary_goal: true
email_update_basic_details:
summary: Email - Update basic_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
basic_details:
name: '{{campaign_name}}'
content_type: PROMOTIONAL
subscription_category: '{{subscription_category}}'
tags:
- '{{tag}}'
email_update_connector:
summary: Email - Update connector
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
connector:
connector_type: '{{connector_type}}'
connector_name: '{{connector_name}}'
email_update_scheduling_details:
summary: Email - Update scheduling_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
scheduling_details:
delivery_type: AT_FIXED_TIME
start_time: '{{start_time}}'
email_update_utm_params:
summary: Email - Update utm_params
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
utm_params:
utm_source: '{{utm_source}}'
utm_medium: email
utm_campaign: '{{utm_campaign}}'
push_update_advanced:
summary: Push - Update advanced
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
advanced:
expiration_settings:
expire_notification_after_value: 24
expire_notification_after_type: HOUR
platform_level_priority:
ios_specific_priority:
apns_priority: '10'
interruption_level: ACTIVE
android_specific_priority:
send_with_priority: true
push_update_control_group_details:
summary: Push - Update control_group_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
control_group_details:
is_campaign_control_group_enabled: true
campaign_control_group_percentage: 10
push_update_basic_details_geofences:
summary: Push - Update basic_details.geofences
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
basic_details:
geofences:
name: '{{geofence_name}}'
latitude: '{{latitude}}'
longitude: '{{longitude}}'
radius: '{{radius_meters}}'
response_time_value: '5'
response_time_granularity: MINUTES
triggered_at: ENTRY
push_update_platform_specific_details:
summary: Push - Update platform_specific_details
value:
request_id: '{{request_id}}'
updated_by: '{{user_email}}'
basic_details:
platform_specific_details:
android:
push_amp_plus_enabled: true
ios:
send_to_all_eligible_device: true
email_update_segmentation_details:
summary: Email - Update segmentation_details
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
segmentation_details:
included_filters:
filter_operator: and
filters:
- filter_type: user_attributes
data_type: string
name: city
operator: in
value: '{{city_value}}'
email_update_delivery_controls:
summary: Email - Update delivery_controls
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
delivery_controls:
bypass_dnd: false
campaign_throttle_rpm: 2000
count_for_frequency_capping: true
email_update_conversion_goal_details:
summary: Email - Update conversion_goal_details
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
conversion_goal_details:
attribution_window_in_hours: 36
goals:
- goal_name: Goal 1
goal_event_name: '{{conversion_event_name}}'
is_primary_goal: true
email_update_control_group_details:
summary: Email - Update control_group_details
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
control_group_details:
is_campaign_control_group_enabled: true
campaign_control_group_percentage: 10
email_update_campaign_audience_limit:
summary: Email - Update campaign_audience_limit (PERIODIC or EVENT_TRIGGERED)
value:
request_id: '{{request_id}}'
channel: EMAIL
campaign_delivery_type: '{{campaign_delivery_type}}'
updated_by: '{{user_email}}'
campaign_audience_limit:
is_campaign_audience_limit_enabled: true
metric: SENT
frequency: TOTAL
limit: 100000
responses:
'200':
description: 'Draft updated successfully.
**Note:** V1 returned `204 No Content` for successful updates. V5 returns `200 OK` with a
response body. Update any integration that checks for `204` to expect `200` instead.
'
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/V5SuccessEnvelope'
- type: object
properties:
data:
$ref: '#/components/schemas/CampaignPatchAcceptedData'
examples:
component_updated:
summary: Component update accepted
value:
response_id: abc-301
type: campaign
data:
id: 64a1b2c3d4e5f6a7b8c9d0e1
'400':
$ref: '#/components/responses/V5ValidationError'
'401':
$ref: '#/components/responses/V5Unauthorized'
'403':
description: 'The caller does not have the required permission to update this campaign.
This occurs when the API credential''s scope does not include campaign update rights,
or when the caller attempts to update a campaign owned by a different team with restricted access.
'
content:
application/json:
schema:
$ref: '#/components/schemas/V5ErrorEnvelope'
example:
response_id: abc-403
error:
code: FORBIDDEN
message: Caller does not have permission to update this campaign.
details: []
'409':
description: 'The campaign is not in a state that allows updates.
This occurs when the campaign is not in `DRAFT` state - for example, it is `ACTIVE`, `PAUSED`,
or `STOPPED`. Only `DRAFT` campaigns can be updated via this endpoint.
'
content:
application/json:
schema:
$ref: '#/components/schemas/V5ErrorEnvelope'
example:
response_id: abc-409
error:
code: BAD_REQUEST
message: Campaign is not in DRAFT state and cannot be patched.
details: []
'429':
description: 'The per-app rate limit for this endpoint has been exceeded. Retry after the window
indicated in the `Retry-After` response header (in seconds).
'
content:
application/json:
schema:
$ref: '#/components/schemas/V5ErrorEnvelope'
example:
response_id: abc-429
error:
code: RATE_LIMITED
message: Rate limit exceeded. Retry after 60 seconds.
details: []
'500':
$ref: '#/components/responses/V5InternalError'
servers:
- url: https://api-{dc}.moengage.com/
description: MoEngage Campaigns API Server
variables:
dc:
default: '01'
description: Data center (DC) segment in the hostname. Replace `OX` with your workspace DC (01–06 or 101). See [Data centers](/api/introduction#data-centers).
/v5/campaigns/{campaign_id}/status:
patch:
operationId: change_campaign_status_v5
summary: Update Campaign Status (V5)
description: 'Applies a state transition to a published campaign. Supported for **Email** and **Push** campaigns.
'
x-mint:
content: '<Note>
This endpoint only handles post-publish lifecycle transitions (STOP, PAUSE, RESUME) for campaigns that are already live. Campaign publishing is not yet supported in V5.
</Note>
<Note>
The response does not include the resulting campaign status. To confirm the new state after a transition, call `GET /v5/campaigns/{campaign_id}`.
</Note>
#### Rate Limits
| Rate Limit Name | Rate Limit |
| :--- | :--- |
| change campaign status per second | The total number of change campaign status requests per second per client is 10. |
| change campaign status per minute | The total number of change campaign status requests per minute per client allowed is 100. |
| change campaign status per hour | The total number of change campaign status requests per hour per client allowed is 6000. |
<Note>
**Notes**
* Breaching the limits will reject the request.
* Per-hour and per-day limits use a rolling window of the last 1 hour and last 24 hours respectively.
</Note>
'
tags:
- Update Campaigns
parameters:
- $ref: '#/components/parameters/MOE-APPKEY'
- $ref: '#/components/parameters/X-MOE-Request-Id'
- name: campaign_id
in: path
required: true
description: Raw 24-char ObjectId of the published campaign to transition.
schema:
type: string
- $ref: '#/components/parameters/Idempotency-Key-Required'
requestBody:
description: Send campaign status change request with action.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignStatusV5Request'
examples:
stop_campaign:
summary: Stop a campaign
value:
request_id: '{{request_id}}'
action: STOP
pause_campaign:
summary: Pause a campaign
value:
request_id: '{{request_id}}'
action: PAUSE
resume_campaign:
summary: Resume a campaign
value:
request_id: '{{request_id}}'
action: RESUME
responses:
'200':
description: Transition accepted.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/V5SuccessEnvelope'
- type: object
properties:
data:
$ref: '#/components/schemas/CampaignStatusTransitionData'
example:
response_id: abc-601
type: campaign
data:
id: 64a1b2c3d4e5f6a7b8c9d0e1
action: STOP
'400':
$ref: '#/components/responses/V5ValidationError'
'401':
$ref: '#/components/responses/V5Unauthorized'
'422':
description: 'The action is not valid for the campaign''s current state or delivery type. Common causes:
- Attempting `STOP` on a Periodic campaign.
- Attempting `PAUSE` or `RESUME` on a One-time campaign.
- Attempting `RESUME` on a campaign that is not in `PAUSED` state.
- Attempting `PAUSE` on a campaign that is not in `ACTIVE`, `SCHEDULED`, or `SENDING` state.
'
content:
application/json:
schema:
$ref: '#/components/schemas/V5ErrorEnvelope'
example:
response_id: abc-422
error:
code: UNPROCESSABLE_ENTITY
message: Action STOP is not valid for a PERIODIC campaign.
details: []
'500':
$ref: '#/components/responses/V5InternalError'
servers:
- url: https://api-{dc}.moengage.com/
description: MoEngage Campaigns API Server
variables:
dc:
default: '01'
description: Data center (DC) segment in the hostname. Replace `OX` with your workspace DC (01–06 or 101). See [Data centers](/api/introduction#data-centers).
/campaigns/{campaign_id}:
patch:
operationId: update_campaign
summary: Update Campaign (V1 — Legacy)
description: 'This API updates an existing Push or Email campaign in MoEngage. You can only update campaigns created via the API, not campaigns created through the MoEngage dashboard.
'
x-mint:
content: "<Note>\n**Differences in V5**\n\n`PATCH /v5/campaigns/{campaign_id}` returns `200 OK` with a response body containing `response_id`, `type`, and `data.id`. V1 returns `204 No Content` with no response body on success. Update any integration that asserts a `204` status code before adopting V5.\n\nSee [Update Campaign (V5)](/api/update-campaigns/update-campaign-v5).\n</Note>\n\n<Warning>\n**Update Restrictions**\n\nYou cannot update campaigns when in **Stopped** or **Archived** state.\n\nFor **Scheduled Campaigns**\n- You can edit all fields **except scheduling type** for One-Time campaigns.\n- You can edit all fields **except scheduling type** for Periodic/Event-Triggered campaigns if no instance has been sent yet.\n\nFor **Active Campaigns**, you cannot edit the following fields:\n- Trigger Condition\n- Segmentation Details\n- Conversion Goal Details\n- Scheduling Type\n- Scheduling Start Date\n\nFor **Event-Triggered campaigns**, updated content is cached and takes up to 30 minutes to take effect.\n</Warning>\n\n#### Rate Limits\n\n| Rate Limit Name | Rate Limit |\n| :--- | :--- |\n| Update campaign per second | The total number of update campaign requests per second per client allowed is 10. |\n| Update campaign per minute | The total number of update campaign requests per minute per client allowed is 100. |\n| Update campaign per hour | The total number of update campaign requests per hour per client allowed is 6000. | \n\n<Note>\n **Notes**\n * Breaching the limits will reject the request.\n * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.\n</Note>\n"
tags:
- Update Campaigns
parameters:
- name: campaign_id
in: path
required: true
description: 'The unique ID of the campaign to update.
You can fetch the campaign ID using the [Get Campaign Details API](/api/get-campaign-details/search-campaigns) by filtering with campaign name, channel, or other criteria.
'
schema:
type: string
example: camp_abc123xyz
- $ref: '#/components/parameters/MOE-APPKEY_2'
requestBody:
description: "In this payload, you can include the fields you want to update.\n\n**Notes:** \n- Pass only the fields you want to update. You don't need to send the complete payload.\n- If updating a field within an object, you must pass the complete object.\n- If updating a nested field, you must pass the complete parent object. For example, to update the title of a Push notification, pass the complete campaign_content object.\n- Use the tabs below to select your campaign type. The schema will adapt based on the selected channel.\n"
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignUpdateRequest'
examples:
push_update_content:
summary: Push - Update Content
value:
request_id: push_update_12345
updated_by: john.doe@example.com
campaign_content:
content:
push:
android:
template_type: BASIC
basic_details:
notification_channel: general
title: Updated Title - Flash Sale!
message: Updated Message - Only 2 hours left!
default_click_action: DEEPLINKING
default_click_action_value: https://example.com/flash-sale
ios:
template_type: BASIC
basic_details:
title: Updated Title - Flash Sale!
message: Updated Message - Only 2 hours left!
default_click_action: DEEPLINKING
default_click_action_value: https://example.com/flash-sale
email_update_content:
summary: Email - Update Content
value:
request_id: email_update_12345
updated_by: john.doe@example.com
campaign_content:
content:
email:
subject: Updated Subject - Last Chance for 50% Off!
preview_text: Sale ends tonight
sender_name: MoEngage Store
from_address: noreply@example.com
reply_to_address: support@example.com
html_content: <!DOCTYPE html><html><body><h1>Last Chance!</h1><p>Sale ends tonight!</p></body></html>
push_update_scheduling:
summary: Push - Update Scheduling
value:
request_id: push_sched_update
updated_by: john.doe@example.com
scheduling_details:
expiry_time: '2026-07-20T13:55:00'
responses:
'204':
$ref: '#/components/responses/NoContent'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
servers:
- url: https://api-{dc}.moengage.com/core-services/v1
description: MoEngage Campaigns API Server
variables:
dc:
default: '01'
description: The ‘dc’ in the API Endpoint URL refers to the MoEngage Data Center (DC). MoEngage hosts each customer in a different DC. You can find your DC number and replace the value of ‘dc’ in the URL by referring to the DC and API endpoint mapping [here](/api/introduction#data-centers). Your MoEngage Data Center (DC) can be 01, 02, 03, 04, 05, 06, or 101.
/campaigns/status:
post:
operationId: change_campaign_status
summary: Change Campaign Status
description: 'This API updates the status of campaigns to stop, pause, or resume them. You can only change the status of campaigns created via the [Create Campaign API](https://www.moengage.com/docs/api/create-campaigns/create-campaign) (not dashboard-created campaigns).
'
x-mint:
content: "<Note>\n**Differences in V5**\n\n`PATCH /v5/campaigns/{campaign_id}/status` accepts one campaign ID as a path parameter per request. V1 accepts a `campaign_ids` array of up to 10 IDs per request. To perform bulk status changes in V5, call the endpoint once per campaign ID.\n\nSee [Update Campaign Status (V5)](/api/update-campaigns/update-campaign-status-v5).\n</Note>\n\n<Note>\n Currently, you can use this API to change the status of Email and Push campaigns. You can update the following statuses of the campaigns:\n - Stop a scheduled One-t
# --- truncated at 32 KB (210 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/moengage/refs/heads/main/openapi/moengage-update-campaigns-api-openapi.yml