openapi: 3.0.3
info:
  title: MoEngage Campaigns API
  version: '2025-11-20'
  description: |
    The MoEngage Campaigns API allows you to create and manage Push and Email campaigns programmatically.
    
    **Supported Channels:**
    - Push (Android, iOS, Web)
    - Email
    
    **Supported Delivery Types:**
    - ONE_TIME
    - PERIODIC
    - EVENT_TRIGGERED
    - BUSINESS_EVENT_TRIGGERED
    - DEVICE_TRIGGERED (Push only)
    - LOCATION_TRIGGERED (Push only)
    - BROADCAST_LIVE_ACTIVITY (Push iOS only)
    
    For more details, visit [MoEngage Developer Documentation](https://developers.moengage.com).
  contact:
    name: MoEngage Developer Team
    email: support@moengage.com
    url: https://developers.moengage.com

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

security:
  - BasicAuth: []

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: |
        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 **Campaign report/Business events/Custom templates/Catalog API/Inform Report** tile.

        For more information on authentication and getting your credentials, refer [here](https://www.moengage.com/docs/api/introduction#getting-your-credentials).

  parameters:
    MOE-APPKEY:
      name: MOE-APPKEY
      in: header
      required: true
      description: |
        This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**.
      schema:
        type: string
      example: "YOUR_WORKSPACE_ID"

  schemas:
    # ==================== Main Request Schema ====================
    CampaignCreateRequest:
      oneOf:
        - $ref: '#/components/schemas/PushCampaignRequest'
        - $ref: '#/components/schemas/EmailCampaignRequest'
      discriminator:
        propertyName: channel
        mapping:
          PUSH: '#/components/schemas/PushCampaignRequest'
          EMAIL: '#/components/schemas/EmailCampaignRequest'

    # ==================== Push Campaign Request ====================
    PushCampaignRequest:
      title: Push Campaign
      type: object
      required:
        - request_id
        - channel
        - campaign_delivery_type
        - created_by
        - basic_details
        - campaign_content
        - segmentation_details
        - scheduling_details
        - delivery_controls
        - advanced
      properties:
        request_id:
          type: string
          description: |
            A unique identifier for this campaign creation request.
            
            **Important:** After successful campaign creation, do not reuse this request_id for the next 1 hour. If campaign creation fails, you can immediately retry with the same request_id.
          example: "push_req_12345"
        channel:
          type: string
          enum:
            - PUSH
          description: The communication channel for this campaign.
        campaign_delivery_type:
          type: string
          enum:
            - ONE_TIME
            - PERIODIC
            - EVENT_TRIGGERED
            - BUSINESS_EVENT_TRIGGERED
            - DEVICE_TRIGGERED
            - LOCATION_TRIGGERED
            - BROADCAST_LIVE_ACTIVITY
          description: The delivery type of the campaign.
        created_by:
          type: string
          format: email
          description: The email ID of the user creating this campaign.
          example: "john.doe@example.com"
        basic_details:
          $ref: '#/components/schemas/PushBasicDetails'
        trigger_condition:
          $ref: '#/components/schemas/PushTriggerCondition'
        campaign_content:
          $ref: '#/components/schemas/PushCampaignContent'
        segmentation_details:
          $ref: '#/components/schemas/SegmentationDetails'
        scheduling_details:
          $ref: '#/components/schemas/SchedulingDetails'
        delivery_controls:
          $ref: '#/components/schemas/PushDeliveryControls'
        advanced:
          $ref: '#/components/schemas/AdvancedDetails'
        conversion_goal_details:
          $ref: '#/components/schemas/ConversionGoalDetails'
        control_group_details:
          $ref: '#/components/schemas/ControlGroupDetails'
        utm_params:
          $ref: '#/components/schemas/UTMParams'

    # ==================== Email Campaign Request ====================
    EmailCampaignRequest:
      title: Email Campaign
      type: object
      required:
        - request_id
        - channel
        - campaign_delivery_type
        - created_by
        - basic_details
        - connector
        - campaign_content
        - segmentation_details
        - scheduling_details
      properties:
        request_id:
          type: string
          description: |
            A unique identifier for this campaign creation request.
            
            **Important:** After successful campaign creation, do not reuse this request_id for the next 1 day. If campaign creation fails, you can immediately retry with the same request_id.
          example: "email_req_12345"
        channel:
          type: string
          enum:
            - EMAIL
          description: The communication channel for this campaign.
        campaign_delivery_type:
          type: string
          enum:
            - ONE_TIME
            - PERIODIC
            - EVENT_TRIGGERED
            - BUSINESS_EVENT_TRIGGERED
          description: The delivery type of the campaign.
        created_by:
          type: string
          format: email
          description: The email ID of the user creating this campaign.
          example: "john.doe@example.com"
        basic_details:
          $ref: '#/components/schemas/EmailBasicDetails'
        trigger_condition:
          $ref: '#/components/schemas/EmailTriggerCondition'
        connector:
          $ref: '#/components/schemas/Connector'
        campaign_content:
          $ref: '#/components/schemas/EmailCampaignCreateContent'
        segmentation_details:
          $ref: '#/components/schemas/SegmentationDetails'
        scheduling_details:
          $ref: '#/components/schemas/SchedulingDetails'
        delivery_controls:
          $ref: '#/components/schemas/EmailDeliveryControls'
        conversion_goal_details:
          $ref: '#/components/schemas/ConversionGoalDetails'
        control_group_details:
          $ref: '#/components/schemas/ControlGroupDetails'
        utm_params:
          $ref: '#/components/schemas/UTMParams'
        campaign_audience_limit:
          $ref: '#/components/schemas/CampaignAudienceLimit'

    # ==================== Campaign Update Request ====================
    CampaignUpdateRequest:
      oneOf:
        - $ref: '#/components/schemas/PushCampaignUpdateRequest'
        - $ref: '#/components/schemas/EmailCampaignUpdateRequest'
      discriminator:
        propertyName: channel
        mapping:
          PUSH: '#/components/schemas/PushCampaignUpdateRequest'
          EMAIL: '#/components/schemas/EmailCampaignUpdateRequest'

    # ==================== Push Campaign Update Request ====================
    PushCampaignUpdateRequest:
      title: Push Campaign
      type: object
      required:
        - request_id
        - updated_by
      properties:
        request_id:
          type: string
          description: A unique identifier for this campaign update request.
          example: "push_update_12345"
        updated_by:
          type: string
          format: email
          description: The email ID of the user updating this campaign.
          example: "john.doe@example.com"
        channel:
          type: string
          enum:
            - PUSH
          description: The communication channel (automatically set to PUSH for this tab).
        basic_details:
          $ref: '#/components/schemas/PushBasicDetails'
        trigger_condition:
          $ref: '#/components/schemas/PushTriggerCondition'
        campaign_content:
          $ref: '#/components/schemas/PushCampaignContent'
        segmentation_details:
          $ref: '#/components/schemas/SegmentationDetails'
        scheduling_details:
          $ref: '#/components/schemas/SchedulingDetails'
        delivery_controls:
          $ref: '#/components/schemas/PushDeliveryControls'
        advanced:
          $ref: '#/components/schemas/AdvancedDetails'
        conversion_goal_details:
          $ref: '#/components/schemas/ConversionGoalDetails'
        control_group_details:
          $ref: '#/components/schemas/ControlGroupDetails'
        utm_params:
          $ref: '#/components/schemas/UTMParams'

    # ==================== Email Campaign Update Request ====================
    EmailCampaignUpdateRequest:
      title: Email Campaign
      type: object
      required:
        - request_id
        - updated_by
      properties:
        request_id:
          type: string
          description: A unique identifier for this campaign update request.
          example: "email_update_12345"
        updated_by:
          type: string
          format: email
          description: The email ID of the user updating this campaign.
          example: "john.doe@example.com"
        channel:
          type: string
          enum:
            - EMAIL
          description: The communication channel (automatically set to EMAIL for this tab).
        basic_details:
          $ref: '#/components/schemas/EmailBasicDetails'
        trigger_condition:
          $ref: '#/components/schemas/EmailTriggerCondition'
        connector:
          $ref: '#/components/schemas/Connector'
        campaign_content:
          $ref: '#/components/schemas/EmailCampaignContent'
        segmentation_details:
          $ref: '#/components/schemas/SegmentationDetails'
        scheduling_details:
          $ref: '#/components/schemas/SchedulingDetails'
        delivery_controls:
          $ref: '#/components/schemas/EmailDeliveryControls'
        conversion_goal_details:
          $ref: '#/components/schemas/ConversionGoalDetails'
        control_group_details:
          $ref: '#/components/schemas/ControlGroupDetails'
        utm_params:
          $ref: '#/components/schemas/UTMParams'
        campaign_audience_limit:
          $ref: '#/components/schemas/CampaignAudienceLimit'

    # ==================== Campaign Search Request ====================
    CampaignSearchRequest:
      type: object
      required:
        - request_id
        - limit
        - page
      properties:
        request_id:
          type: string
          description: A unique identifier for this search request.
          example: "search_req_12345"
        campaign_fields:
          $ref: '#/components/schemas/CampaignSearchFields'
        include_child_campaigns:
          type: boolean
          description: |
            Whether to include child campaigns (flow nodes and periodic children).
            
            Set to `true` to fetch details of periodic child campaigns and flow campaign nodes. Flow campaigns can be identified by the presence of `flow_id` and `flow_name` in the response.
          default: false
        include_archive_campaigns:
          type: boolean
          description: Whether to include archived campaigns in the results.
          default: false
        limit:
          type: integer
          description: |
            The number of campaigns to display per page.
            
            **Maximum:** 15
          minimum: 1
          maximum: 15
          example: 10
        page:
          type: integer
          description: |
            The page number to retrieve.
            
            For example, if there are 200 campaigns and the limit is 10, there will be 20 pages.
          minimum: 1
          example: 1

    CampaignSearchFields:
      type: object
      description: Filter criteria for searching campaigns.
      properties:
        channels:
          type: array
          items:
            type: string
            enum:
              - PUSH
              - EMAIL
              - SMS
          description: Filter campaigns by channel type.
          example: ["PUSH", "EMAIL"]
        created_by:
          type: array
          items:
            type: string
            format: email
          description: |
            Filter campaigns by the email ID of the user who created them.
            
            **Note:** Only email IDs are supported.
          example: ["john.doe@example.com"]
        created_date:
          type: object
          description: Filter campaigns by creation date range.
          properties:
            from_date:
              type: string
              format: date
              description: |
                The starting point of the date range.
                
                **Recommended format:** YYYY-MM-DD
              example: "2024-01-01"
            to_date:
              type: string
              format: date
              description: |
                The ending point of the date range.
                
                **Recommended format:** YYYY-MM-DD
              example: "2024-12-31"
        delivery_type:
          type: array
          items:
            type: string
            enum:
              - ONE_TIME
              - PERIODIC
              - EVENT_TRIGGERED
              - BUSINESS_EVENT_TRIGGERED
              - DEVICE_TRIGGERED
              - LOCATION_TRIGGERED
              - BROADCAST_LIVE_ACTIVITY
          description: Filter campaigns by delivery type.
          example: ["ONE_TIME", "PERIODIC"]
        id:
          type: string
          description: Filter by specific campaign ID.
          example: "camp_abc123xyz"
        name:
          type: string
          description: Filter by campaign name.
          example: "Summer Sale Campaign"
        status:
          type: array
          items:
            type: string
            enum:
              - ACTIVE
              - SCHEDULED
              - PAUSED
              - SENT
              - STOPPED
              - ARCHIVED
          description: Filter campaigns by status.
          example: ["ACTIVE", "SCHEDULED"]
        tags:
          type: array
          items:
            type: string
          description: Filter campaigns by tags.
          example: ["sale", "promotion"]

    # ==================== Campaign Test Request ====================
    CampaignTestRequest:
      oneOf:
        - $ref: '#/components/schemas/PushCampaignTestRequest'
        - $ref: '#/components/schemas/EmailCampaignTestRequest'
      discriminator:
        propertyName: channel
        mapping:
          PUSH: '#/components/schemas/PushCampaignTestRequest'
          EMAIL: '#/components/schemas/EmailCampaignTestRequest'

    # ==================== Push Campaign Test Request ====================
    PushCampaignTestRequest:
      title: Push Campaign
      type: object
      required:
        - request_id
        - channel
        - basic_details
        - campaign_content
        - test_campaign_meta
      properties:
        request_id:
          type: string
          description: A unique identifier for this test request.
          example: "test_push_12345"
        channel:
          type: string
          enum:
            - PUSH
          description: The communication channel (automatically set to PUSH for this tab).
        basic_details:
          $ref: '#/components/schemas/PushBasicDetails'
        campaign_content:
          $ref: '#/components/schemas/PushCampaignContent'
        personalization_details:
          $ref: '#/components/schemas/PersonalizationDetails'
        test_campaign_meta:
          $ref: '#/components/schemas/PushTestCampaignMeta'

    # ==================== Email Campaign Test Request ====================
    EmailCampaignTestRequest:
      title: Email Campaign
      type: object
      required:
        - request_id
        - channel
        - basic_details
        - connector
        - campaign_content
        - test_campaign_meta
      properties:
        request_id:
          type: string
          description: A unique identifier for this test request.
          example: "test_email_12345"
        channel:
          type: string
          enum:
            - EMAIL
          description: The communication channel (automatically set to EMAIL for this tab).
        basic_details:
          $ref: '#/components/schemas/EmailBasicDetails'
        connector:
          $ref: '#/components/schemas/Connector'
        campaign_content:
          $ref: '#/components/schemas/EmailCampaignContent'
        utm_params:
          $ref: '#/components/schemas/UTMParams'
        personalization_details:
          $ref: '#/components/schemas/PersonalizationDetails'
        test_campaign_meta:
          $ref: '#/components/schemas/EmailTestCampaignMeta'

    # ==================== Personalization Details ====================
    PersonalizationDetails:
      type: object
      description: |
        Override values for personalizing campaign content during testing.
        
        **Important**: 
          - When you pass personalization details in the personalization_details object of this API, MoEngage uses those details to personalize the user attributes or event attributes present in the content instead of the attributes present in the user profile.
          - You can use this API only for 10 users at a time.
          - The same personalization details are used across all users. For example, you pass the first name as Dave in personalization details, you have used the first name in the content, and there are 10 users. In this case, all 10 users will get the same first name (Dave).
      properties:
        user_attributes:
          type: object
          additionalProperties: true
          description: |
            Key-value pairs for user attribute personalization.
            
            The same values are used for all test recipients.
          example:
            First Name: "John"
            Last Name: "Doe"
            Email: "john.doe@example.com"
        event_attributes:
          type: object
          additionalProperties: true
          description: |
            Key-value pairs for event attribute personalization.
            
            If you pass only a subset of attributes, remaining values are picked from the user profile.
          example:
            Campaign Name: "Test Campaign"
            Campaign Channel: "Email"

    # ==================== Push Test Campaign Meta ====================
    PushTestCampaignMeta:
      type: object
      description: Metadata for specifying test recipients for Push campaigns.
      required:
        - identifier
        - identifier_values
      properties:
        identifier:
          type: string
          enum:
            - USER_ATTRIBUTE_UNIQUE_ID
            - USER_ATTRIBUTE_USER_EMAIL
            - USER_ATTRIBUTE_USER_MOBILE
            - MOE_GAID
            - ADVERTISING_IDENTIFIER
            - PUSH_ID
            - CUSTOM_SEGMENT
          description: |
            The type of identifier used to target test users.
            
            - **USER_ATTRIBUTE_UNIQUE_ID**: Permanent internal user ID (e.g., USER_1138)
            - **USER_ATTRIBUTE_USER_EMAIL**: User's email address (e.g., john.doe@example.com)
            - **USER_ATTRIBUTE_USER_MOBILE**: User's mobile number (e.g., +14155550101)
            - **MOE_GAID**: Google Advertising ID from Android device
            - **ADVERTISING_IDENTIFIER**: Resettable advertising ID (GAID on Android, IDFA on iOS)
            - **PUSH_ID**: Unique device token for push notifications
            - **CUSTOM_SEGMENT**: User-defined segment for targeting
        identifier_values:
          type: array
          items:
            type: string
          description: Array of identifier values to send the test campaign to.
          example: ["user_12345", "user_67890"]
        locale_name:
          type: string
          description: The locale name to use for the test campaign (when using multi-locale campaigns).
        variation:
          type: string
          description: The variation name to use for the test campaign (when using A/B testing).
          example: "variation_1"

    # ==================== Email Test Campaign Meta ====================
    EmailTestCampaignMeta:
      type: object
      description: |
        Metadata for specifying test recipients for Email campaigns.
      required:
        - identifier
        - identifier_values
      properties:
        identifier:
          type: string
          enum:
            - EMAIL
            - ID
            - CUSTOM_SEGMENT
            - MOBILE_NUMBER
          description: |
            The type of identifier used to target test users.
            
            - **EMAIL**: Email address (content will not be personalized with user profile data)
            - **ID**: User ID from your system
            - **CUSTOM_SEGMENT**: User-defined segment
            - **MOBILE_NUMBER**: User's mobile phone number
        identifier_values:
          type: array
          items:
            type: string
          description: |
            Array of identifier values to send the test campaign to.
            
            **Note:** Maximum 10 users at a time.
          maxItems: 10
          example: ["john.doe@example.com", "jane.smith@example.com"]
        locale_name:
          type: string
          description: The locale name to use for the test campaign (when using multi-locale campaigns).
          example: "en-US"
        variation:
          type: string
          description: The variation name to use for the test campaign (when using A/B testing).
          example: "variation_1"

    # ==================== Test Campaign Success Response ====================
    TestCampaignSuccessResponse:
      type: object
      description: Response after successfully sending a test campaign.
      properties:
        data:
          type: object
          additionalProperties:
            type: object
            properties:
              status:
                type: string
                enum:
                  - success
                  - failed
                description: The status of the test campaign delivery for this identifier.
              failure_reason:
                type: string
                description: The reason for failure (only present if status is "failed").
          description: |
            Object containing test results for each identifier.
            
            Each key is an identifier value with its delivery status.
          example:
            user_12345:
              status: "success"
            user_67890:
              status: "failed"
              failure_reason: "User not found"
        message:
          type: string
          description: A success message.
          example: "Test campaign created successfully"

    # ==================== Campaign Meta Request ====================
    CampaignMetaRequest:
      type: object
      required:
        - request_id
        - limit
        - page
      properties:
        request_id:
          type: string
          description: A unique identifier for this metadata retrieval request.
          example: "meta_req_12345"
        campaign_fields:
          $ref: '#/components/schemas/CampaignMetaSearchFields'
        include_child_campaigns:
          type: boolean
          description: |
            Whether to include child campaign information.
            
            Set to `true` to fetch details of child campaigns (flow nodes and periodic children). Use `flow_id`, `flow_name`, or `parent_campaign_id` in the response to identify relationships.
          default: false
        limit:
          type: integer
          description: |
            The number of campaigns to display per page.
            
            **Maximum:** 15
          minimum: 1
          maximum: 15
          example: 15
        page:
          type: integer
          description: |
            The page number to retrieve.
            
            For example, if there are 200 campaigns and limit is 10, there will be 20 pages.
          minimum: 1
          example: 1

    CampaignMetaSearchFields:
      type: object
      description: Filter criteria for retrieving campaign metadata.
      properties:
        id:
          type: string
          description: The unique identifier to identify the campaign.
          example: "camp_abc123xyz"
        channels:
          type: array
          items:
            type: string
            enum:
              - EMAIL
              - PUSH
              - SMS
              - WHATSAPP
              - FACEBOOK
              - GOOGLE ADS
              - CONNECTORS
          description: Filter campaigns by channel type.
          example: ["EMAIL", "PUSH"]
        created_by:
          type: array
          items:
            type: string
            format: email
          description: |
            Filter by email ID of the user who created the campaign.
            
            **Note:** Only email IDs are supported.
          example: ["john.doe@example.com"]
        created_date:
          type: object
          description: Filter campaigns by creation date range.
          required:
            - from_date
            - to_date
          properties:
            from_date:
              type: string
              description: |
                The starting point of the date range in which campaigns were created.
                
                **Recommended format:** YYYY-MM-DD or DD-MM-YYYY
              example: "2024-01-01"
            to_date:
              type: string
              description: |
                The ending point of the date range in which campaigns were created.
                
                **Recommended format:** YYYY-MM-DD or DD-MM-YYYY
              example: "2024-12-31"
        delivery_type:
          type: array
          items:
            type: string
            enum:
              - ONE_TIME
              - PERIODIC
              - EVENT_TRIGGERED
              - BUSINESS_EVENT_TRIGGERED
          description: Filter campaigns by delivery type.
          example: ["ONE_TIME"]
        name:
          type: string
          description: Filter by campaign name.
          example: "Summer Sale Campaign"
        status:
          type: array
          items:
            type: string
            enum:
              - SCHEDULED
              - ACTIVE
              - PAUSED
              - SENT
              - STOPPED
              - RETIRED
              - ARCHIVED
          description: |
            Filter campaigns by status.

            `RETIRED` is a terminal status applied automatically to campaigns that have reached their end condition (for example, a campaign whose end date has passed). Retired campaigns cannot be reactivated. This status is distinct from `STOPPED` (manually halted) and `ARCHIVED` (explicitly archived by a user).
          example: ["SCHEDULED", "ACTIVE"]
        tags:
          type: array
          items:
            type: string
          description: Filter campaigns by tags that describe the campaign's nature or theme.
          example: ["promotion", "sale"]

    # ==================== Campaign Meta Response ====================
    CampaignMetaResponse:
      type: object
      description: Campaign metadata including basic information and reachability details.
      properties:
        campaign_id:
          type: string
          description: The unique ID of the campaign.
          example: "camp_abc123xyz"
        channel:
          type: string
          enum:
            - EMAIL
            - PUSH
            - SMS
            - WHATSAPP
            - FACEBOOK
            - GOOGLE ADS
            - CONNECTORS
          description: The communication channel.
        platform:
          type: array
          items:
            type: string
            enum:
              - ANDROID
              - IOS
              - WEB
          description: The platform types supported for the campaign (applicable for Push).
        created_by:
          type: string
          format: email
          description: The email ID of the user who created the campaign.
        campaign_delivery_type:
          type: string
          enum:
            - ONE_TIME
            - PERIODIC
            - EVENT_TRIGGERED
            - BUSINESS_EVENT_TRIGGERED
            - DEVICE_TRIGGERED
            - LOCATION_TRIGGERED
            - BROADCAST_LIVE_ACTIVITY
          description: The delivery type of the campaign.
        campaign_name:
          type: string
          description: The name of the campaign.
          example: "Summer Sale Campaign"
        campaign_team:
          type: string
          description: The team name associated with the campaign.
        campaign_tags:
          type: array
          items:
            type: string
          description: Tags associated with the campaign.
        campaign_status:
          type: string
          enum:
            - SCHEDULED
            - ACTIVE
            - PAUSED
            - SENT
            - STOPPED
            - RETIRED
            - ARCHIVED
          description: |
            The current status of the campaign.

            `RETIRED` is a terminal status applied automatically to campaigns that have reached their end condition. Retired campaigns cannot be reactivated and are distinct from `STOPPED` (manually halted) and `ARCHIVED` (explicitly archived).
        campaign_start_time:
          type: string
          format: date-time
          description: The start time of the campaign in ISO 8601 format. This value is returned in UTC.
          example: "2024-11-28T12:18:00"
        parent_campaign_id:
          type: string
          description: |
            The campaign ID of the parent campaign.
            
            Only shown if the requested campaign_id belongs to a child campaign and `include_child_campaigns` is true.
        total_child_campaigns:
          type: integer
          description: |
            The number of child campaigns.
            
            Only shown if the campaign_id belongs to a parent campaign. Only applicable for periodic campaigns.
        reachability_details:
          type: object
          description: |
            Reachability information for the campaign.
            
            **Important:** Only populated for **scheduled** campaigns (one-time, business event-triggered, and event-triggered).
            Reachability is calculated once daily and cached for 24 hours.
          properties:
            count:
              type: integer
              description: The estimated number of users the scheduled campaign will reach.
              example: 18182
            last_updated_time:
              type: string
              format: date-time
              description: The timestamp when reachability was last calculated, in ISO 8601 format. This value is returned in UTC.
              example: "2024-11-27T09:05:42.661000"

    # ==================== Campaign Status Change Request ====================
    CampaignStatusChangeRequest:
      type: object
      description: You can request to change the status of one or more campaigns.
      required:
        - request_id
        - action
        - campaign_ids
      properties:
        request_id:
          type: string
          description: A unique identifier for this status change request.
          example: "status_change_12345"
        action:
          type: string
          enum:
            - STOP
            - PAUSE
            - RESUME
          description: |
            The action to perform on the campaign(s).
            
            - **STOP**: Stop a scheduled One-time campaign (cannot be used for Periodic campaigns). After a One-time campaign moves to Active state, it cannot be stopped.
            - **PAUSE**: Pause a running Periodic or Event-triggered campaign. `PAUSE` is not supported for `BUSINESS_EVENT_TRIGGERED`, `DEVICE_TRIGGERED`, or `LOCATION_TRIGGERED` campaigns.
            - **RESUME**: Resume a paused Periodic or Event-triggered campaign. `RESUME` is not supported for `BUSINESS_EVENT_TRIGGERED`, `DEVICE_TRIGGERED`, or `LOCATION_TRIGGERED` campaigns.
        campaign_ids:
          type: array
          items:
            type: string
          description: |
            Array of campaign IDs whose status you want to change.
            
            **Maximum:** 10 campaign IDs per request
          minItems: 1
          maxItems: 10
          example: ["camp_abc123", "camp_def456"]

    # ==================== Global Control Group Request ====================
    GlobalControlGroupRequest:
      type: object
      description: Request to add or remove users from the Global Control Group (GCG).
      required:
        - request_id
        - file_url
        - action_type
        - updated_by
      properties:
        request_id:
          type: string
          description: Unique identifier of the request to update the Global Control Group.
          example: "{{request_id}}"
        file_url:
          type: string
          format: uri
          description: |
            Publicly accessible URL of the CSV file for processing. The file must contain a single column named `uid` followed by the respective user IDs in new rows. The file must be under 300 MB and downloadable without authentication.

            **Note:** Currently, only publicly accessible Amazon S3 URLs are supported.
          example: "https://example.csv"
        action_type:
          type: string
          enum:
            - add
            - remove
          description: The operation to perform on users in the Global Control Group.
        updated_by:
          type: string
          format: email
          description: The email ID of the user initiating the update.
          example: "john.doe@xyz.com"

    # ==================== Get Child Campaigns Request ====================
    GetChildCampaignsRequest:
      type: object
      description: You can request to retrieve child campaign execution details.
      required:
        - request_id
        - limit
        - page
      properties:
        request_id:
          type: string
          description: A unique identifier for this child campaigns retrieval request.
          example: "child_req_12345"
        limit:
          type: integer
          description: |
            The number of child campaigns to display per page.
            
            **Maximum:** 15
          minimum: 1
          maximum: 15
          example: 15
        page:
          type: integer
          description: |
            The page number to retrieve.
            
            For example, if there are 100 child campaigns and limit is 10, there will be 10 pages.
          minimum: 1
          example: 1

    # ==================== Child Campaigns Response ====================
    ChildCampaignsResponse:
      type: object
      description: Response containing child campaign execution details.
      properties:
        executions:
          type: array
          description: Array of child campaign execution details.
          items:
            type: object
            properties:
              campaign_id:
                type: string
                description: The unique ID of the child campaign.
                example: "camp_child_001"
              sent_time:
                type: string
                description: The timestamp when the child campaign was sent, in UTC.
                example: "2024-06-24T14:30:18.908000"
              status:
                type: string
                enum:
                  - Sent
                  - Sending
                  - Scheduled
                  - Failed
                description: The status of the child campaign.
        total_instances:
          type: integer
          description: The total number of times the parent campaign has been executed.
          example: 8

    # ==================== Personalized Preview Request ====================
    PersonalizedPreviewRequest:
      type: object
      required:
        - request_id
        - personalization_content
        - personalization_details
      properties:
        request_id:
          type: string
          description: A unique identifier for this personalization preview request.
          example: "preview_req_12345"
        personalization_content:
          type: object
          description: |
            The content to personalize.
            
            **Note:** Either `payload` or `custom_template_data` must be provided.
          properties:
            payload:
              type: object
              additionalProperties: true
              description: |
                Flexible key-value pairs containing content to personalize.
                
                Can include any name and number of keys with HTML, text, or Jinja templates.
              example:
                email_html: "<!DOCTYPE html><html><body><p>Hi {{UserAttribute['First Name']}}</p></body></html>"
            custom_template_data:
              type: object
              description: |
                Custom template information.
                
                **Required fields when using custom templates:**
                - template_id
                - version
              properties:
                template_id:
                  type: string
                  description: The ID of the custom template.
                  example: "5b7d04c6-8ddc-4957-80d9-c67266079609"
                version:
                  type: string
                  description: The version of the custom template.
                  example: "1"
        user_details:
          type: object
          description: |
            Information about the user to preview for.
            
            **Note:** If using user_details, both `identifier` and `identifier_value` are mandatory.
          properties:
            identifier:
              type: string
              description: |
                The type of unique identifier used to specify the user.
                
                Can be ID, email, phone number, etc.
              example: "ID"
            identifier_value:
              type: string
              description: The corresponding value of the selected identifier.
              example: "USER_12345"
        personalization_details:
          type: object
          description: |
            **Important**:
              - When you pass personalization_details, MoEngage uses those values to personalize content instead of actual user profile data.
              - Attributes must exist in the MoEngage dashboard.
              - If an attribute does not exist and default value is not “MOE_NOT_SEND”, it will appear empty.
              - Event attributes can be used when the same event is used for the campaign.
              - You can use event attributes to personalize content APIs when the same event is used for the campaign.
          required:
            - channel
          properties:
            channel:
              type: string
              enum:
                - EMAIL
                - PUSH
                - SMS
              description: The channel for which to preview personalized content.
            event_name:
              type: string
              description: |
                The event name for personalization.
                
                **Required** if event attributes are present in the payload.
              example: "App_Opened"
            user_attributes:
              type: object
              additionalProperties: true
              description: |
                Key-value pairs representing specific user characteristics.
                
                Can contain any name and number of keys.
              example:
                First Name: "John"
                Last Name: "Doe"
                Gender: "Male"
            event_attributes:
              type: object
              additionalProperties: true
              description: |
                Key-value pairs describing properties of a particular event.
                
                Can contain any name and number of keys.
              example:
                App_Version: "1.0.2"
                Campaign Name: "Summer Sale"

    # ==================== Personalized Preview Response ====================
    PersonalizedPreviewResponse:
      type: object
      description: Response containing the personalized content.
      properties:
        personalized_content:
          type: object
          description: The personalized content with all attributes resolved.
          properties:
            payload:
              type: object
              additionalProperties: true
              description: |
                The personalized content with all user/event attributes and personalization elements resolved.
                
                Structure mirrors the input payload with personalized values filled in.

    # ==================== Campaign Details Response ====================
    CampaignDetailsResponse:
      type: object
      description: Detailed information about a campaign.
      properties:
        campaign_id:
          type: string
          description: The unique ID of the campaign.
          example: "camp_abc123xyz"
        status:
          type: string
          enum:
            - ACTIVE
            - SCHEDULED
            - PAUSED
            - SENT
            - STOPPED
            - ARCHIVED
          description: The current status of the campaign.
        channel:
          type: string
          enum:
            - PUSH
            - EMAIL
            - SMS
          description: The communication channel.
        campaign_delivery_type:
          type: string
          enum:
            - ONE_TIME
            - PERIODIC
            - EVENT_TRIGGERED
            - BUSINESS_EVENT_TRIGGERED
            - DEVICE_TRIGGERED
            - LOCATION_TRIGGERED
            - BROADCAST_LIVE_ACTIVITY
          description: The delivery type of the campaign.
        created_by:
          type: string
          format: email
          description: The email ID of the user who created the campaign.
        updated_by:
          type: string
          format: email
          description: The email ID of the user who last updated the campaign.
        created_at:
          type: string
          description: The timestamp when the campaign was created, in UTC.
          example: "2024-07-04 08:00:54.847000"
        updated_at:
          type: string
          description: The timestamp when the campaign was last updated, in UTC.
        sent_time:
          type: string
          description: The timestamp when the campaign was sent, in UTC.
          example: "2024-07-04 20:32:00"
        flow_id:
          type: string
          description: |
            The flow ID (only for flow campaigns).
            
            Only applicable when `include_child_campaigns` is true.
        flow_name:
          type: string
          description: |
            The flow name (only for flow campaigns).
            
            Only applicable when `include_child_campaigns` is true.
        parent_id:
          type: string
          description: |
            The campaign ID of the parent campaign.
            
            Only applicable for periodic child campaigns when `include_child_campaigns` is true.
        basic_details:
          type: object
          description: |
            Basic details of the campaign.
            
            Structure varies by channel (Push/Email/SMS).
        campaign_content:
          type: object
          description: The campaign content including locales and variations.
        trigger_condition:
          type: object
          description: |
            Trigger condition details for event-triggered campaigns.
            Structure varies by channel (Push supports INTELLIGENT_DELAY, Email does not).
        segmentation_details:
          $ref: '#/components/schemas/SegmentationDetails'
        scheduling_details:
          $ref: '#/components/schemas/SchedulingDetails'
        delivery_controls:
          type: object
          description: Delivery control settings for the campaign.
        advanced:
          type: object
          description: Advanced campaign settings (for Push campaigns).
        conversion_goal_details:
          $ref: '#/components/schemas/ConversionGoalDetails'
        control_group_details:
          $ref: '#/components/schemas/ControlGroupDetails'
        utm_params:
          $ref: '#/components/schemas/UTMParams'
        connector:
          type: object
          description: |
            Connector configuration (for Email and SMS campaigns).
          properties:
            connector_type:
              type: string
              example: "SENDGRID"
            connector_name:
              type: string
              example: "default"
        sender_name:
          type: string
          description: |
            The sender name configured for the campaign.
            
            Only applicable for SMS campaigns.
        campaign_audience_limit:
          $ref: '#/components/schemas/CampaignAudienceLimit'

    # ==================== Push Basic Details ====================
    PushBasicDetails:
      type: object
      description: Contains the basic information about the Push campaign.
      required:
        - name
        - platforms
        - platform_specific_details
      properties:
        name:
          type: string
          description: The name of the campaign.
          example: "Summer Sale Push Notification"
        business_event:
          type: string
          description: |
            The business event to be mapped to the campaign.
            
            **Required** for BUSINESS_EVENT_TRIGGERED campaigns.
          example: "user_signup"
        tags:
          type: array
          items:
            type: string
          description: Tags that provide context about the campaign's nature or theme.
          example: ["activation", "summer_sale"]
        team:
          type: string
          description: |
            The name of the team collaborating on this campaign.
            For more information, refer to [Teams in MoEngage](/user-guide/settings/account/team-management/teams-in-moengage).
          example: "marketing_team"
        platforms:
          type: array
          items:
            type: string
            enum:
              - ANDROID
              - IOS
              - WEB
          description: The platforms to target for this Push campaign.
          example: ["ANDROID", "IOS"]
        broadcast_live_activity_id:
          type: string
          description: |
            The broadcast live activity ID for iOS Live Activities.
            
            **Required** when platform is iOS and delivery_type is BROADCAST_LIVE_ACTIVITY.
          example: "live_check123"
        geofences:
          $ref: '#/components/schemas/Geofences'
        send_to_triggered_platform_only:
          type: boolean
          description: Whether to send the campaign only to the platform that triggered the event. Applicable for event-triggered campaigns.
        platform_specific_details:
          $ref: '#/components/schemas/PlatformSpecificDetails'

    # ==================== Email Basic Details ====================
    EmailBasicDetails:
      type: object
      description: Contains the basic information about the Email campaign.
      required:
        - name
        - content_type
        - user_attribute_identifier
      properties:
        name:
          type: string
          description: The name of the campaign.
          example: "Summer Sale Email"
        business_event:
          type: string
          description: |
            The business event to be mapped to the campaign.
            
            **Required** for BUSINESS_EVENT_TRIGGERED campaigns.
          example: "user_signup"
        content_type:
          type: string
          enum:
            - PROMOTIONAL
            - TRANSACTIONAL
          description: The type of content in the campaign.
        subscription_category:
          type: string
          description: |
            The subscription category for promotional email campaigns.
            This targets only users who have opted-in to receive communication about this category.
            
            **Required** for PROMOTIONAL email campaigns.
          example: "music"
        tags:
          type: array
          items:
            type: string
          description: Tags that provide context about the campaign's nature or theme.
          example: ["activation", "summer_sale"]
        team:
          type: string
          description: |
            The name of the team collaborating on this campaign.
            For more information, refer to [Teams in MoEngage](/user-guide/settings/account/team-management/teams-in-moengage).
          example: "marketing_team"
        user_attribute_identifier:
          type: string
          description: |
            The user attribute that stores the email address.

            Standard identifier is `MOE_EMAIL_ID`.
          example: "MOE_EMAIL_ID"
          default: "MOE_EMAIL_ID"
        send_only_double_opt_in_users:
          type: boolean
          description: |
            Whether to send the campaign only to users who have completed double opt-in.

            When `false` or omitted, the campaign sends to all eligible users.

            Ensure the Double Opt-In feature is enabled for your workspace.
          default: false
          example: true
        deduplication_attribute:
          type: string
          description: |
            The user attribute used for brand deduplication.

            Pass `""` (empty string) or omit the field to treat the campaign as single-brand. For multi-brand deduplication, pass the backend attribute name that stores the brand identifier (for example, `u_em`).

            Always use the backend attribute name (for example, `u_em`), not the display label (for example, `Email (Standard)`).

            Ensure the Brand Deduplication feature is enabled for your workspace.
          default: ""
          example: "u_em"

    # ==================== Platform Specific Details ====================
    PlatformSpecificDetails:
      type: object
      description: Platform-specific configuration details.
      properties:
        android:
          type: object
          properties:
            push_amp_plus_enabled:
              type: boolean
              description: Whether Push Amp+ feature is enabled for this campaign.
              default: false
        ios:
          type: object
          properties:
            send_to_all_eligible_device:
              type: boolean
              description: Whether to send the campaign to all eligible devices.
            exclude_provisional_push_devices:
              type: boolean
              description: Whether to exclude provisional push devices.
            send_to_only_provisional_push_enabled_devices:
              type: boolean
              description: Whether to send only to provisional push-enabled devices.
          description: |
            **Note:** You must pass one of these keys as true for iOS.

    # ==================== Geofences ====================
    Geofences:
      type: object
      description: |
        Geofence location details for location-triggered campaigns.
        
        **Required** for LOCATION_TRIGGERED campaigns.
      required:
        - name
        - latitude
        - longitude
        - radius
        - response_time_value
        - response_time_granularity
        - triggered_at
      properties:
        name:
          type: string
          description: The unique name of the geofence location being targeted.
        latitude:
          type: string
          description: The latitude coordinate for the center of the geofence area.
        longitude:
          type: string
          description: The longitude coordinate for the center of the geofence area.
        radius:
          type: string
          description: The radius in meters from the center point that defines the boundary of the geofence.
        dwell_time_value:
          type: string
          description: |
            The numeric value for the time to wait before sending the message after the trigger condition is met.
            
            **Required** when triggered_at is set to "dwell".
        dwell_time_granularity:
          type: string
          enum:
            - MINUTES
            - HOURS
            - DAYS
          description: |
            The time unit for the dwell_time_value.
            
            **Required** when triggered_at is set to "dwell".
        response_time_value:
          type: string
          description: The numeric value for the time to wait before sending the message after the trigger condition is met.
        response_time_granularity:
          type: string
          enum:
            - MINUTES
            - HOURS
            - DAYS
          description: The time unit for the response_time_value.
        triggered_at:
          type: string
          enum:
            - ENTRY
            - EXIT
            - dwell
          description: The user action that triggers the campaign (when user enters/exits the geofence).

    # ==================== Trigger Condition ====================
    PushTriggerCondition:
      type: object
      description: |
        Trigger condition details for Push event-triggered campaigns.
        
        **Required** for EVENT_TRIGGERED campaigns.
      properties:
        included_filters:
          $ref: '#/components/schemas/FilterGroup'
        secondary_included_filters:
          $ref: '#/components/schemas/FilterGroup'
        trigger_delay_type:
          type: string
          enum:
            - DELAY
            - ASAP
            - INTELLIGENT_DELAY
          description: |
            The type of triggered delay.
            
            When set to DELAY, the following fields are mandatory:
            - trigger_delay_value
            - trigger_delay_granularity
            - trigger_relation
        trigger_delay_value:
          type: integer
          description: The numeric value of the triggered delay.
        trigger_delay_granularity:
          type: string
          enum:
            - MINUTES
            - HOURS
            - DAYS
          description: The time unit for the trigger delay.
        trigger_relation:
          type: string
          enum:
            - BEFORE
            - AFTER
          description: |
            The trigger relation with delay.
            
            **Required** when trigger_delay_type is DELAY.
        trigger_attr:
          type: object
          description: The attribute value of the trigger.
        intelligent_delay_optimization:
          type: object
          description: |
            Configuration for intelligent delay optimization.
            
            Used when trigger_delay_type is INTELLIGENT_DELAY. Defines a time window (min/max delay) within which the system finds the optimal moment to send the message.
          properties:
            min_delay_value:
              type: integer
              description: The numeric component of the lower bound for the intelligent delay window.
            min_delay_granularity:
              type: string
              enum:
                - MINUTES
                - HOURS
              description: The time unit that qualifies the min_delay_value.
            max_delay_value:
              type: integer
              description: The numeric component of the upper bound for the intelligent delay window.
            max_delay_granularity:
              type: string
              enum:
                - HOURS
                - DAYS
              description: The time unit that qualifies the max_delay_value.

    EmailTriggerCondition:
      type: object
      description: |
        Trigger condition details for Email event-triggered campaigns.
        
        **Required** for EVENT_TRIGGERED campaigns.
      properties:
        included_filters:
          $ref: '#/components/schemas/FilterGroup'
        secondary_included_filters:
          $ref: '#/components/schemas/FilterGroup'
        trigger_delay_type:
          type: string
          enum:
            - DELAY
            - ASAP
          description: |
            The type of triggered delay.
            
            When set to DELAY, the following fields are mandatory:
            - trigger_delay_value
            - trigger_delay_granularity
            - trigger_relation
        trigger_delay_value:
          type: integer
          description: The numeric value of the triggered delay.
        trigger_delay_granularity:
          type: string
          enum:
            - MINUTES
            - HOURS
            - DAYS
          description: The time unit for the trigger delay.
        trigger_relation:
          type: string
          enum:
            - BEFORE
            - AFTER
          description: |
            The trigger relation with delay.
            
            **Required** when trigger_delay_type is DELAY.
        trigger_attr:
          type: object
          description: The attribute value of the trigger.

    # ==================== Push Campaign Content ====================
    PushCampaignContent:
      type: object
      description: Contains the content and variations for the Push campaign.
      required:
        - content
      properties:
        locales:
          type: array
          items:
            type: string
          description: |
            List of locales for multi-language campaigns.
            You can send campaigns in multiple languages using locales.
          example: ["en-US", "es-ES", "default"]
        variation_details:
          $ref: '#/components/schemas/VariationDetails'
        content:
          type: object
          description: The actual Push campaign content.
          required:
            - push
          properties:
            push:
              $ref: '#/components/schemas/PushContent'

    # ==================== Email Campaign Content ====================
    EmailCampaignContent:
      type: object
      description: Contains the content and variations for the Email campaign.
      required:
        - content
      properties:
        locales:
          type: array
          items:
            type: string
          description: |
            List of locales for multi-language campaigns.
            You can send campaigns in multiple languages using locales.
          example: ["en-US", "es-ES", "default"]
        variation_details:
          $ref: '#/components/schemas/VariationDetails'
        content:
          type: object
          description: The actual Email campaign content.
          required:
            - email
          properties:
            email:
              $ref: '#/components/schemas/EmailContent'

    # ==================== Email Campaign Content (Create) ====================
    EmailCampaignCreateContent:
      type: object
      description: |
        Contains the content and variations for the Email campaign.

        This is the Create Campaign variant of `EmailCampaignContent`. It accepts the same fields, plus the link branding and deep linking domains, which can only be set when the campaign is created.
      required:
        - content
      properties:
        locales:
          type: array
          items:
            type: string
          description: |
            List of locales for multi-language campaigns.
            You can send campaigns in multiple languages using locales.
          example: ["en-US", "es-ES", "default"]
        variation_details:
          $ref: '#/components/schemas/VariationDetails'
        content:
          type: object
          description: The actual Email campaign content.
          required:
            - email
          properties:
            email:
              $ref: '#/components/schemas/EmailCreateContent'

    # ==================== Email Content (Create) ====================
    EmailCreateContent:
      description: |
        The Email content accepted by the Create Campaign API. Includes every field in `EmailContent`, plus the domain settings below.
      allOf:
        - $ref: '#/components/schemas/EmailContent'
        - type: object
          properties:
            link_branding_domain:
              type: string
              description: |
                The custom domain used to brand links in the email body, in place of the standard MoEngage domain. This is referred to as **Link branding** in the MoEngage dashboard.

                If not provided, the workspace's default link branding domain (if configured) is used.
              example: "yourbrand.com"
            deep_link_domain:
              type: string
              description: |
                The deep linking domain used to wrap deep links in the email body, directing recipients to specific in-app or web content instead of a generic landing page.
              example: "deeplink.yourbrand.com"

    # ==================== Variation Details ====================
    VariationDetails:
      type: object
      description: Configuration for A/B testing variations.
      required:
        - distribution_type
        - no_of_variations
      properties:
        distribution_type:
          type: string
          enum:
            - SHERPA
            - MANUAL
          description: The distribution type for variations.
        no_of_variations:
          type: integer
          description: The number of variations for the campaign.
          minimum: 1
          example: 2
        manual_distribution_percentage:
          type: object
          description: |
            Manual percentage distribution for each variation.
            
            **Required** when distribution_type is MANUAL.
          additionalProperties:
            type: string
          example:
            variation_1: "50"
            variation_2: "45"
        sherpa_campaign_duration:
          type: integer
          description: |
            The Sherpa campaign duration.
            
            **Required** when distribution_type is SHERPA.
        sherpa_distribution_metric:
          type: string
          enum:
            - OPEN RATE
            - CLICK RATE
            - BOTH
          description: |
            The Sherpa distribution metric.
            
            **Required** when distribution_type is SHERPA.

    # ==================== Push Content ====================
    PushContent:
      type: object
      description: Push notification content for Android, iOS, and Web platforms.
      properties:
        android:
          $ref: '#/components/schemas/AndroidPushContent'
        ios:
          $ref: '#/components/schemas/IOSPushContent'
        web:
          $ref: '#/components/schemas/WebPushContent'

    # ==================== Android Push Content ====================
    AndroidPushContent:
      type: object
      description: Android push notification content.
      required:
        - template_type
      properties:
        template_type:
          type: string
          enum:
            - BASIC
            - STYLIZED_BASIC
            - SIMPLE_IMAGE_CAROUSEL
            - IMAGE_BANNER_WITH_TEXT
            - TIMER
            - TIMER_WITH_PROGRESS_BAR
            - Custom
          description: |
            The type of Android push template.
            
            **Note:** If you are passing a template ID, set template_type to "Custom".
        custom_template_id:
          type: string
          description: |
            The ID of the custom template.
            
            **Required** when template_type is "Custom".
        custom_template_version:
          type: integer
          description: The version of the custom template.
        basic_details:
          $ref: '#/components/schemas/AndroidBasicDetails'
        timer:
          $ref: '#/components/schemas/AndroidTimer'
        buttons:
          type: array
          description: Action buttons for the notification.
          items:
            $ref: '#/components/schemas/AndroidButton'
        advanced:
          $ref: '#/components/schemas/AndroidAdvanced'
        template_backup:
          $ref: '#/components/schemas/AndroidTemplateBackup'

    AndroidBasicDetails:
      type: object
      description: |
        Basic details for the Android push notification. 
        
        Fields vary by template_type. All templates support common fields like title, message, default_click_action.
      required:
        - notification_channel
        - title
        - message
        - default_click_action
        - default_click_action_value
      properties:
        notification_channel:
          type: string
          description: The Android notification channel where the push will be sent.
          example: "general"
        include_app_name_and_time:
          type: boolean
          description: |
            Whether to include the application's name and timestamp within the banner image.
            
            **Supported Templates:** Image Banner with Text
        background_color_code:
          type: string
          description: |
            The hex code for the notification's background color.
            
            **Supported Templates:** Stylized Basic, Simple Image Carousel, Image Banner with Text
          example: "#9a4444"
        app_name_color_code:
          type: string
          description: |
            The hex code for the color of the application's name text.
            
            **Supported Templates:** Stylized Basic, Simple Image Carousel, Image Banner with Text
          example: "#dea1a1"
        notification_control_color:
          type: string
          enum:
            - LIGHT
            - DARK
          description: |
            The color scheme for the notification's control elements (action buttons).
            
            **Supported Templates:** Stylized Basic, Simple Image Carousel, Image Banner with Text
        include_title_and_message:
          type: boolean
          description: |
            Whether to include the notification's title and message text within the banner image.
            
            **Supported Templates:** Image Banner with Text
        apply_background_color_in_text_editor:
          type: boolean
          description: |
            Whether to apply the specified background color within the rich text editor for preview.
            
            **Supported Templates:** Stylized Basic, Simple Image Carousel, Image Banner with Text
        title:
          type: string
          description: The main title of the push notification.
          example: "Limited Time Offer!"
        message:
          type: string
          description: |
            The message body of the push notification.
            
            You can use HTML in the message parameter to apply rich text formatting, including text color and styles.
          example: "Get 50% off on all items. Shop now!"
        summary:
          type: string
          description: The summary text for the notification.
        image_url:
          type: string
          format: uri
          description: The image URL for the push notification.
          example: "https://example.com/images/promo.jpg"
        image_scaling:
          type: string
          enum:
            - FIT_INSIDE_IMAGE_CONTAINER
            - FILL_IMAGE_CONTAINER
          description: |
            The scaling behavior for images within the carousel template.
            
            **Supported Templates:** Simple Image Carousel, Image Banner with Text
        banner_image_url:
          type: string
          format: uri
          description: |
            The URL for the background image used in the Image Banner Text template.
            
            **Required for:** Image Banner with Text template
        input_gif_url:
          type: string
          format: uri
          description: |
            The URL for the GIF media used in the push campaign content.
            
            **Supported Templates:** Basic
        collapsed_push_notification:
          type: string
          description: |
            The configuration for the notification's collapsed state (view before user expands it).
            
            **Supported Templates:** Image Banner with Text
          example: "SAME_AS_TEMPLATE_BACKUP"
        carousel_content:
          $ref: '#/components/schemas/CarouselContent'
        default_click_action:
          type: string
          enum:
            - DEEPLINKING
            - NAVIGATE_TO_A_SCREEN
            - RICH_LANDING
          description: The action performed when the main body of the notification is clicked.
        default_click_action_value:
          type: string
          description: The URL or deep link to open when the notification is clicked.
          example: "https://example.com/sale"
        key_value_pairs:
          type: array
          items:
            $ref: '#/components/schemas/KeyValuePair'
          description: Custom key-value pairs for the notification payload.

    CarouselContent:
      type: object
      description: |
        Configuration for image carousel in Simple Image Carousel template.
        
        **Required for:** Simple Image Carousel template
      required:
        - slider_transition
        - slide_data
      properties:
        slider_transition:
          type: string
          enum:
            - manual
            - automatic
          description: The transition type for the carousel slides.
        slide_data:
          type: array
          description: Array of slide configurations.
          items:
            type: object
            required:
              - image_url
            properties:
              image_url:
                type: string
                format: uri
                description: The image URL for this slide.
              image_click_action:
                type: string
                enum:
                  - DEEPLINKING
                  - RICH_LANDING
                  - NAVIGATE_TO_A_SCREEN
                description: The click action for this slide's image.
              image_click_action_value:
                type: string
                description: |
                  The click action value for this slide's image.
                  
                  **Required** when image_click_action is provided.
              key_value_pairs:
                type: array
                items:
                  $ref: '#/components/schemas/KeyValuePair'

    AndroidTimer:
      type: object
      description: |
        Timer configuration for Timer and Timer with Progress Bar templates.
        
        **Required for:** TIMER and TIMER_WITH_PROGRESS_BAR templates
      required:
        - timer_ends_at
        - personalized_value
      properties:
        timer_ends_at:
          type: string
          enum:
            - DURATION
            - SPECIFIC_TIME_USER_TIMEZONE
            - SPECIFIC_TIME_CAMPAIGN_TIMEZONE
          description: How the timer's endpoint is determined.
        specific_time:
          type: string
          format: date-time
          description: |
            The specific time when the timer ends.
            
            **Required** when personalized_value is true.
        time_period:
          type: string
          description: |
            The time period for the timer.
            
            **Required** when timer_ends_at is SPECIFIC_TIME_USER_TIMEZONE or SPECIFIC_TIME_CAMPAIGN_TIMEZONE.
        personalized_value:
          type: boolean
          description: |
            Whether the timer duration is personalized per user.
            
            If false, all users get the same duration.
        duration_hour:
          type: string
          description: |
            The number of hours the timer will run for.
            
            **Required** when personalized_value is false.
          example: "2"
        duration_minute:
          type: string
          description: |
            The number of minutes the timer will run for (in addition to hours).
            
            **Required** when personalized_value is false.
          example: "30"

    AndroidButton:
      type: object
      description: Action button configuration for Android push notifications.
      required:
        - btn_name
        - click_action_type
        - click_action_value
      properties:
        btn_name:
          type: string
          description: The text to be displayed on the button.
          example: "Shop Now"
        click_action_type:
          type: string
          enum:
            - DEEPLINKING
            - NAVIGATE_TO_A_SCREEN
            - RICH_LANDING
            - CALL
            - SHARE
            - COPY
            - SET_USER_ATTRIBUTE
            - TRACK_EVENT
            - CUSTOM_ACTION
          description: The type of action to perform when the button is clicked.
        click_action_name:
          type: string
          description: The name of the click action.
        click_action_value:
          type: string
          description: The URL or deep link to open for the button's action.
          example: "https://example.com/product"
        key_value_pairs:
          type: array
          items:
            $ref: '#/components/schemas/KeyValuePair'
          description: Custom key-value pairs specific to this button's click event.

    AndroidAdvanced:
      type: object
      description: Advanced configuration options for Android push notifications.
      properties:
        coupon_code:
          type: string
          description: The coupon code to be included in the push payload.
          example: "SUMMER50"
        icon_type_in_notification:
          type: string
          description: The icon type to be included in the push payload.
          example: "app_icon"
        use_large_icon:
          type: boolean
          description: Whether to use a large icon in the notification.
        make_notification_sticky:
          type: boolean
          description: |
            When enabled, the user cannot swipe away the notification.
        dismiss_button_text:
          type: string
          description: |
            The text to display on the dismiss button.
            
            **Required** when make_notification_sticky is true or auto_dismiss_notification is true.
        auto_dismiss_notification:
          type: boolean
          description: Whether the notification can be auto-dismissed.
        auto_dismiss_notification_time_value:
          type: integer
          description: |
            The time value after which to auto-dismiss the notification.
            
            **Required** when auto_dismiss_notification is true.
        auto_dismiss_notification_time_granularity:
          type: string
          enum:
            - DAYS
            - HOURS
            - MINUTES
          description: |
            The time unit for auto-dismiss.
            
            **Required** when auto_dismiss_notification is true.
        group_key:
          type: string
          description: |
            The group key used to identify and categorize related push notifications.
            
            **Note:**
            - Use the same group key for all push notifications you want to group
            - MoEngage automatically modifies the group key to ensure it doesn't exceed 45 characters
            - Non-Latin scripts, special characters, and spaces are removed
        collapse_replace_key:
          type: string
          description: |
            The update key used to identify and update related push notifications.
            
            Ensure you use the same update key for all push notifications intended to update each other.

    AndroidTemplateBackup:
      type: object
      description: |
        Fallback notification content for when the template cannot be rendered.
        
        **Required for:** Stylized Basic, Simple Image Carousel, Image Banner with Text, Timer, and Timer with Progress Bar templates
      required:
        - title
        - message
        - default_click_action
        - default_click_action_value
      properties:
        title:
          type: string
          description: The title for the fallback notification.
        message:
          type: string
          description: The message body for the fallback notification.
        summary:
          type: string
          description: The summary for the fallback notification.
        image_url:
          type: string
          format: uri
          description: The URL of an image for the fallback notification.
        default_click_action:
          type: string
          enum:
            - DEEPLINKING
            - NAVIGATE_TO_A_SCREEN
            - RICH_LANDING
          description: The default click action for the fallback notification.
        default_click_action_value:
          type: string
          description: The URL or deep link for the fallback's click action.
        key_value_pairs:
          type: array
          items:
            $ref: '#/components/schemas/KeyValuePair'
          description: Custom key-value pairs specific to the fallback payload.

    KeyValuePair:
      type: object
      description: A key-value pair for custom data.
      required:
        - key
        - value
      properties:
        key:
          type: string
          description: The key name.
        value:
          type: string
          description: The value.

    # ==================== iOS Push Content ====================
    IOSPushContent:
      type: object
      description: iOS push notification content.
      required:
        - template_type
      properties:
        template_type:
          type: string
          enum:
            - BASIC
            - STYLIZED_BASIC
            - SIMPLE_IMAGE_CAROUSEL
            - Custom
          description: The type of iOS push template.
        custom_template_id:
          type: string
          description: |
            The ID of the custom template.
            
            **Required** when template_type is "Custom".
        custom_template_version:
          type: integer
          description: The version of the custom template.
        basic_details:
          $ref: '#/components/schemas/IOSBasicDetails'
        buttons:
          type: array
          description: Action buttons for the notification.
          items:
            $ref: '#/components/schemas/IOSButton'
        advanced:
          $ref: '#/components/schemas/IOSAdvanced'
        template_backup:
          $ref: '#/components/schemas/IOSTemplateBackup'

    IOSBasicDetails:
      type: object
      description: Basic details for the iOS push notification.
      required:
        - title
        - message
      properties:
        background_color_code:
          type: string
          description: |
            The hexadecimal color code for the notification's background.
            
            **Supported Templates:** Simple Image Carousel, Stylized Basic
          example: "#a0a0a0"
        apply_background_color_in_text_editor:
          type: boolean
          description: |
            Whether to apply the background color within the text editor view.
            
            **Supported Templates:** Simple Image Carousel, Stylized Basic
        title:
          type: string
          description: The main title of the push notification.
          example: "New Message"
        message:
          type: string
          description: The main body text of the notification.
          example: "You have a new message waiting for you"
        subtitle:
          type: string
          description: The subtitle displayed below the main title.
        allow_bg_refresh:
          type: boolean
          description: Whether to allow the app to be woken up in the background to refresh content.
        rich_media_type:
          type: string
          enum:
            - Image
            - Video
            - GIF
          description: |
            The type of rich media to be included in the notification.
            
            **Supported Templates:** Basic
        rich_media_value:
          type: string
          format: uri
          description: |
            The URL of the rich media asset specified in the rich_media_type field.
            
            **Supported Templates:** Basic
        image_url:
          type: string
          format: uri
          description: |
            The URL of a large image to be displayed within the notification content.
            
            **Note:** Required when template_type is SIMPLE_IMAGE_CAROUSEL.
        input_gif_url:
          type: string
          format: uri
          description: |
            The URL for the GIF media used in the push campaign content.
            
            **Supported Templates:** Basic, Stylized Basic
        carousel_content:
          $ref: '#/components/schemas/IOSCarouselContent'
        default_click_action:
          type: string
          enum:
            - DEEPLINKING
            - NAVIGATE_TO_A_SCREEN
            - RICH_LANDING
          description: The action performed when the main body of the notification is tapped.
        default_click_action_value:
          type: string
          description: The URL or deep link associated with the default click action.
        key_value_pairs:
          type: array
          items:
            $ref: '#/components/schemas/KeyValuePair'
          description: Custom key-value pairs sent with the push payload for in-app handling.

    IOSCarouselContent:
      type: object
      description: |
        Configuration for image carousel in Simple Image Carousel template.
        
        **Required for:** Simple Image Carousel template
      required:
        - slider_transition
        - slide_data
      properties:
        slider_transition:
          type: string
          enum:
            - MANUAL
            - AUTOMATIC
          description: The transition type for the carousel slides.
        slide_data:
          type: array
          description: Array of slide configurations.
          items:
            type: object
            required:
              - image_url
            properties:
              image_url:
                type: string
                format: uri
                description: The image URL for this slide.
              image_click_action:
                type: string
                enum:
                  - DEEPLINKING
                  - RICH_LANDING
                  - NAVIGATE_TO_A_SCREEN
                description: The click action for this slide's image.
              image_click_action_value:
                type: string
                description: The click action value for this slide's image.
              key_value_pairs:
                type: array
                items:
                  $ref: '#/components/schemas/KeyValuePair'

    IOSButton:
      type: object
      description: Action button configuration for iOS push notifications.
      required:
        - button_category
      properties:
        button_category:
          type: string
          description: |
            The pre-defined category name for a set of interactive buttons configured in the app.
          example: "MOE_PUSH_TEMPLATE"

    IOSAdvanced:
      type: object
      description: Advanced configuration options for iOS push notifications.
      properties:
        coupon_code:
          type: string
          description: The coupon code to be included in the push payload.
        sound_file:
          type: string
          description: The name of a custom sound file located in the app bundle to play upon receiving the notification.
        enable_ios_badge:
          type: boolean
          description: Whether this campaign allows the notification to increment the app's badge count.
        group_key:
          type: string
          description: |
            The group key used to identify and categorize related push notifications.
            
            **Note:**
            - Use the same group key for all push notifications you want to group
            - MoEngage automatically modifies the group key to ensure it doesn't exceed 45 characters
            - Non-Latin scripts, special characters, and spaces are removed
        collapse_replace_key:
          type: string
          description: |
            The update key used to identify and update related push notifications.
            
            Ensure you use the same update key for all push notifications intended to update each other.

    IOSTemplateBackup:
      type: object
      description: |
        Fallback notification content for when the template cannot be rendered.
        
        **Required for:** Stylized Basic and Simple Image Carousel templates
      required:
        - title
        - message
      properties:
        title:
          type: string
          description: The title for the fallback notification.
        message:
          type: string
          description: The message body for the fallback notification.
        subtitle:
          type: string
          description: The subtitle for the fallback notification.
        allow_bg_refresh:
          type: boolean
          description: Whether to enable background app refresh for the fallback notification.
        rich_media_type:
          type: string
          enum:
            - Image
            - Video
            - GIF
          description: The type of media attachment for the fallback.
        rich_media_value:
          type: string
          format: uri
          description: The URL of the media attachment for the fallback.
        default_click_action:
          type: string
          enum:
            - DEEPLINKING
            - NAVIGATE_TO_A_SCREEN
            - RICH_LANDING
          description: The default click action for the fallback notification.
        default_click_action_value:
          type: string
          description: The URL or deep link for the fallback's click action.
        key_value_pairs:
          type: array
          items:
            $ref: '#/components/schemas/KeyValuePair'
          description: Custom key-value pairs specific to the fallback payload.

    # ==================== Web Push Content ====================
    WebPushContent:
      type: object
      description: Web push notification content.
      required:
        - template_type
        - basic_details
      properties:
        template_type:
          type: string
          enum:
            - BASIC
          description: The template type for web push (currently only BASIC is supported).
        basic_details:
          $ref: '#/components/schemas/WebBasicDetails'
        buttons:
          type: array
          description: Action buttons for the notification.
          items:
            $ref: '#/components/schemas/WebButton'
        advanced:
          $ref: '#/components/schemas/WebAdvanced'

    WebBasicDetails:
      type: object
      description: Basic details for the Web push notification.
      required:
        - title
        - message
        - redirect_url
      properties:
        title:
          type: string
          description: The title text displayed at the top of the notification.
          example: "Special Offer"
        message:
          type: string
          description: The main body text of the notification.
          example: "Check out our latest deals!"
        redirect_url:
          type: string
          format: uri
          description: The URL that the user is redirected to when they click the main body of the notification.
          example: "https://example.com/offers"
        image_url:
          type: string
          format: uri
          description: The URL of a large image to be displayed within the notification content.
        auto_dismiss_notification:
          type: boolean
          description: Whether the notification should auto-dismiss.

    WebButton:
      type: object
      description: Action button configuration for Web push notifications.
      required:
        - title
      properties:
        title:
          type: string
          description: The text displayed on the button.
          example: "View Offer"
        icon_url:
          type: string
          format: uri
          description: The URL of an icon to be displayed next to the button text.
        url:
          type: string
          format: uri
          description: The destination URL that the user is redirected to when they click this button.

    WebAdvanced:
      type: object
      description: Advanced configuration options for Web push notifications.
      properties:
        icon_image_type:
          type: string
          enum:
            - DEFAULT
            - ICON_URL
          description: The type of icon to use for the notification.
        icon_url:
          type: string
          format: uri
          description: The URL for a custom notification icon.

    # ==================== SMS Content ====================
    SMSContent:
      type: object
      description: SMS campaign content.
      properties:
        template_id:
          type: string
          description: The ID of the SMS template.
        message:
          type: string
          description: The content of the SMS message.
          example: "Hi! Get 20% discount - visit https://example.com/sale"
        shorten_and_track_url:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
                format: uri
                description: The URL to be shortened and tracked.
              is_click_tracking_enabled:
                type: boolean
                description: Whether click tracking is enabled for this URL.
          description: URLs to be shortened and tracked.
        opt_out_status:
          type: boolean
          description: The opt-out status for the SMS campaign.
        custom_template_id:
          type: string
          description: The ID of the custom SMS template.
        custom_template_version:
          type: integer
          description: The version of the custom template.

    # ==================== Email Content ====================
    EmailContent:
      type: object
      description: Email campaign content.
      required:
        - subject
        - sender_name
        - from_address
        - reply_to_address
      properties:
        subject:
          type: string
          description: The subject line of the email.
          example: "Exclusive Summer Sale - 50% Off!"
        preview_text:
          type: string
          description: The preview text shown in email clients.
          example: "Dont miss out on our biggest sale of the season"
        sender_name:
          type: string
          description: The name of the sender that appears in the email.
          example: "MoEngage Team"
        from_address:
          type: string
          format: email
          description: The sender's email address.
          example: "noreply@moengage.com"
        reply_to_address:
          type: string
          format: email
          description: The reply-to email address.
          example: "support@moengage.com"
        cc_ids:
          type: array
          items:
            type: string
            format: email
          description: Email addresses to CC.
        bcc_ids:
          type: array
          items:
            type: string
            format: email
          description: Email addresses to BCC.
        html_content:
          type: string
          description: |
            The HTML content of the email.
            
            **Optional** if custom_template_id is provided.
          example: "<!DOCTYPE html><html><head></head><body><p>Hello {{UserAttribute['First Name']}}</p></body></html>"
        email_editor:
          type: string
          enum:
            - Froala Editor
            - Ace Editor
          description: |
            The HTML editor used for the email campaign.
            
            - **Required** if you want to create the campaign using the `Ace Editor`.
            - **Optional** if you want to use the default `Froala Editor`.
          example: "Ace Editor"
        custom_template_id:
          type: string
          description: |
            The ID of a custom email template.
            
            **Optional** if html_content is provided.
            
            When this field is provided, the following fields are not required:
            - subject
            - preview_text
            - sender_name
        custom_template_version:
          type: integer
          description: The version of the custom template.
        attachments:
          type: array
          items:
            type: object
            properties:
              file_type:
                type: string
                enum:
                  - URL
                  - PERSONALIZED_ATTACHMENT
              url:
                type: string
              s3_keys:
                type: array
                items:
                  type: string
                description: S3 object keys backing an attachment stored in S3.
                example: ["attachments/2026/06/invoice-001.pdf"]
          description: Attachments to include in the email.
        gmail_annotations:
          $ref: '#/components/schemas/GmailAnnotations'

    # ==================== Gmail Annotations ====================
    GmailAnnotations:
      type: object
      description: |
        Gmail Annotations shown in Gmail's Promotions tab. Two annotation types are supported: `deal_card` and `product_carousel`. These are mutually exclusive — include only one per campaign.

        **Note:** `gmail_annotations` is only supported when `content_type` is `PROMOTIONAL`. Using it with `TRANSACTIONAL` returns a `400` error.
      required:
        - send_email_if_personalization_fails
        - sender_logo
        - sender_logo_type
      properties:
        send_email_if_personalization_fails:
          type: boolean
          description: |
            Whether to send the email if personalization of any Gmail annotation field fails.

            **Required** when `gmail_annotations` is present.
          example: true
        sender_logo:
          type: string
          description: |
            The sender logo shown in the Gmail annotation.

            Accepts a valid HTTPS URL or a MoEngage personalization token.

            **Required** when `gmail_annotations` is present.
          example: "https://example.com/logo.png"
        sender_logo_type:
          type: string
          enum:
            - image_url
            - uploaded_image
          description: |
            The source type of the sender logo.

            **Required** when `sender_logo` is provided.
          example: "image_url"
        deal_card:
          description: |
            The Deal Card annotation.

            **Optional.** Use either `deal_card` or `product_carousel` — not both.
          allOf:
            - $ref: '#/components/schemas/GmailAnnotationsDealCard'
        product_carousel:
          description: |
            The Product Carousel annotation.

            **Optional.** Use either `product_carousel` or `deal_card` — not both.
          allOf:
            - $ref: '#/components/schemas/GmailAnnotationsProductCarousel'

    GmailAnnotationsDealCard:
      type: object
      description: |
        Deal Card annotation shown in Gmail's Promotions tab. All four fields below are required when `deal_card` is present.
      required:
        - description
        - discount_code
        - availability_starts
        - availability_ends
      properties:
        description:
          type: string
          description: |
            Short deal description shown in the Gmail annotation.

            **Required** when `deal_card` is present.
          example: "Get 20% off on all orders above $50"
        discount_code:
          type: string
          description: |
            Promo or discount code displayed with the deal.

            **Required** when `deal_card` is present.
          example: "SAVE20"
        availability_starts:
          type: string
          description: |
            ISO 8601 datetime indicating when the deal becomes active. Use the timezone of the promotion, not your server or API caller timezone. Ensure the timezone matches the promotion's local timezone so the deal displays the correct active and expiry times for your audience.

            **Accepted formats:**
            - UTC (`Z` suffix): `YYYY-MM-DDTHH:mm:ssZ` (for example, `2026-06-01T00:00:00Z`).
            - Positive offset: `YYYY-MM-DDTHH:mm:ss+HH:MM` (for example, `2026-06-01T00:00:00+05:30` for IST).
            - Negative offset: `YYYY-MM-DDTHH:mm:ss-HH:MM` (for example, `2026-06-01T00:00:00-07:00` for US Pacific PDT).

            **Common offsets:** IST `+05:30`, SGT `+08:00`, GST `+04:00`, CET `+01:00` or `+02:00` (DST), EST `-05:00`, EDT `-04:00`, PST `-08:00`, PDT `-07:00`, UTC `Z` or `+00:00`.

            **Required** when `deal_card` is present.
          example: "2026-06-01T00:00:00Z"
        availability_ends:
          type: string
          description: |
            ISO 8601 datetime indicating when the deal expires. Same format as `availability_starts`.

            Use the timezone of the promotion, not your server or API caller timezone. Ensure the timezone matches the promotion's local timezone so the deal displays the correct active and expiry times for your audience.

            Must be at least 1 hour after `availability_starts`.

            **Required** when `deal_card` is present.
          example: "2026-06-30T23:59:59Z"

    GmailAnnotationsProductCarousel:
      type: object
      description: |
        Product Carousel annotation shown in Gmail's Promotions tab.

        Use `MANUAL` to specify products directly in the request, or `PRODUCT_SET` to pull products dynamically from a MoEngage Catalog product set.
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - MANUAL
            - PRODUCT_SET
          description: |
            The source type for the product carousel.

            - `MANUAL`: Specify products directly in the request using `manual_data`.
            - `PRODUCT_SET`: Pull products dynamically from a MoEngage Catalog product set using `product_set_data`. Requires the Product Sets feature to be enabled for your workspace.

            **Required** when `product_carousel` is present.
        manual_data:
          description: |
            Products specified directly in the request.

            **Required** when `product_carousel.type` is `MANUAL`.
          allOf:
            - $ref: '#/components/schemas/GmailAnnotationsProductCarouselManualData'
        product_set_data:
          description: |
            Reference to a MoEngage Catalog product set.

            **Required** when `product_carousel.type` is `PRODUCT_SET`.
          allOf:
            - $ref: '#/components/schemas/GmailAnnotationsProductCarouselProductSetData'

    GmailAnnotationsProductCarouselManualData:
      type: object
      description: |
        Manual product list for the Gmail Annotations product carousel.

        **Required** when `product_carousel.type` is `MANUAL`. Minimum 2 products required.
      required:
        - currency
        - products
      properties:
        currency:
          type: string
          description: |
            ISO 4217 currency code applied to all products in the carousel.

            **Required** when `manual_data` is present.
          example: "USD"
        products:
          type: array
          description: |
            List of products to display in the carousel.

            **Required** when `manual_data` is present. Minimum 2 products.
          minItems: 2
          items:
            $ref: '#/components/schemas/GmailAnnotationsProductCarouselManualProduct'

    GmailAnnotationsProductCarouselManualProduct:
      type: object
      description: A single product entry in a manual product carousel. All fields below are required for each product.
      required:
        - id
        - headline
        - original_price
        - discount_value
        - discount_type
        - promo_url
        - product_image
      properties:
        id:
          type: string
          description: |
            Unique product identifier.

            **Required** for each product.
          example: "prod-001"
        headline:
          type: string
          description: |
            Product name shown in the annotation.

            **Required** for each product.
          example: "Wireless Headphones"
        original_price:
          type: string
          description: |
            Original price of the product as a numeric string.

            **Required** for each product.
          example: "199.99"
        discount_value:
          type: string
          description: |
            Discount amount as a numeric string. Interpreted as a percentage or absolute value depending on `discount_type`.

            **Required** for each product.
          example: "30"
        discount_type:
          type: string
          enum:
            - PERCENT
            - VALUE
          description: |
            How `discount_value` is interpreted.

            - `PERCENT`: `discount_value` is a percentage.
            - `VALUE`: `discount_value` is an absolute amount in `currency`.

            **Required** for each product.
          example: "PERCENT"
        promo_url:
          type: string
          description: |
            Product landing page URL. Must be a valid HTTPS URL.

            **Required** for each product.
          example: "https://example.com/products/prod-001"
        product_image:
          type: string
          description: |
            Product image URL. Must be a valid HTTPS URL. Cannot be empty.

            **Required** for each product.
          example: "https://example.com/images/prod-001.png"

    GmailAnnotationsProductCarouselProductSetData:
      type: object
      description: |
        Product set configuration for the Gmail Annotations product carousel. Pulls products dynamically from a MoEngage Catalog product set.

        **Required** when `product_carousel.type` is `PRODUCT_SET`. Requires the Product Sets feature to be enabled for your workspace.
      required:
        - product_set
        - image_url
        - headline
        - promo_url
        - product_count
      properties:
        product_set:
          type: string
          description: |
            Product set ID from MoEngage Catalog. Must be valid and exist in your workspace.

            **Required** when `product_set_data` is present.
          example: "product_set_12345"
        image_url:
          type: string
          description: |
            Fallback image URL if a product set image is unavailable.

            **Required** when `product_set_data` is present.
          example: "https://example.com/images/fallback.png"
        headline:
          type: string
          description: |
            Label shown for the product carousel.

            **Required** when `product_set_data` is present.
          example: "Recommended For You"
        promo_url:
          type: string
          description: |
            Destination URL when the user clicks the annotation.

            **Required** when `product_set_data` is present.
          example: "https://example.com/shop"
        product_count:
          type: integer
          description: |
            Number of products to display.

            **Required** when `product_set_data` is present. Minimum 2, maximum 9.
          minimum: 2
          maximum: 9
          example: 3

    # ==================== Segmentation Details ====================
    SegmentationDetails:
      type: object
      description: Defines the target audience for the campaign.
      properties:
        included_filters:
          $ref: '#/components/schemas/FilterGroup'
        excluded_filters:
          $ref: '#/components/schemas/FilterGroup'
        is_all_user_campaign:
          type: boolean
          description: Whether to include all users in the campaign.
        send_campaign_to_opt_out_users:
          type: boolean
          description: Whether to send the campaign to users who have opted out.

    FilterGroup:
      type: object
      description: |
        A group of filters combined with a logical operator.
        
        For detailed segmentation payload and supported fields, refer to [Create Custom Segment](/api/filter-segments/create-filter-segment).
      required:
        - filter_operator
        - filters
      properties:
        filter_operator:
          type: string
          enum:
            - and
            - or
          description: The logical operator to combine filters.
        filters:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/UserAttributeFilter'
              - $ref: '#/components/schemas/ActionFilter'
              - $ref: '#/components/schemas/CustomSegmentFilter'
          description: |
            The list of filters to be combined using the filter operator.
            
            Supported filter types:
            - User attributes-based filters
            - Action-based filters (with or without attributes)
            - Custom segments

    UserAttributeFilter:
      type: object
      description: Filter based on user attributes.
      required:
        - filter_type
        - data_type
        - name
        - operator
      properties:
        filter_type:
          type: string
          enum:
            - user_attributes
        data_type:
          type: string
          enum:
            - string
            - double
            - datetime
            - bool
          description: The data type of the attribute being filtered.
        category:
          type: string
          description: The category of the attribute (e.g., "Tracked Standard Attribute").
        name:
          type: string
          description: The name of the attribute to filter on (e.g., "uid").
        operator:
          type: string
          description: |
            The operator to use in the filter. Allowed values depend on data_type:
            - 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
        value:
          description: The value to filter on (not required for 'exists' operator).
        case_sensitive:
          type: boolean
          description: Whether the filter comparison should be case-sensitive.
        negate:
          type: boolean
          description: Whether to negate the filter condition.
        project_name:
          type: string
          description: |
            The name of the project associated with the user attributes.
            
            **Required** if the Portfolio feature is enabled in your workspace.

    ActionFilter:
      type: object
      description: Filter based on user actions/events.
      required:
        - filter_type
        - action_name
      properties:
        filter_type:
          type: string
          enum:
            - actions
        action_name:
          type: string
          description: The name of the action/event to filter on.
        execution:
          type: object
          properties:
            type:
              type: string
              enum:
                - atleast
                - atmost
                - exactly
            count:
              type: integer
        executed:
          type: boolean
          description: Whether the action was executed.
        attributes:
          $ref: '#/components/schemas/FilterGroup'
        condition:
          type: string
          description: The condition type (e.g., "IF").

    CustomSegmentFilter:
      type: object
      description: Filter using a custom segment.
      required:
        - filter_type
        - id
      properties:
        filter_type:
          type: string
          enum:
            - custom_segments
        name:
          type: string
          description: The name of the custom segment.
        id:
          type: string
          description: The ID of the custom segment.

    # ==================== Scheduling Details ====================
    SchedulingDetails:
      type: object
      description: Defines when the campaign should be sent. All date-time values must be passed in UTC.
      required:
        - delivery_type
      properties:
        delivery_type:
          type: string
          enum:
            - ASAP
            - AT_FIXED_TIME
            - SEND_IN_BTS
            - SEND_IN_USER_TIMEZONE
          description: When to deliver the campaign.
        start_time:
          type: string
          format: date-time
          description: |
            The start time for the campaign in ISO 8601 format. Pass this value in UTC.

            Example: "2024-06-21T12:59:00"
        expiry_time:
          type: string
          format: date-time
          description: The expiry time for the campaign in ISO 8601 format. Pass this value in UTC.
        periodic_details:
          $ref: '#/components/schemas/PeriodicDetails'
        bts_details:
          $ref: '#/components/schemas/BTSDetails'
        user_timezone_details:
          $ref: '#/components/schemas/UserTimezoneDetails'

    PeriodicDetails:
      type: object
      description: |
        Configuration for periodic campaigns.
        
        **Required** for PERIODIC campaigns.
      properties:
        sending_frequency:
          type: string
          enum:
            - DAILY
            - WEEKLY
            - MONTHLY
          description: The frequency to send the campaign.
        repeat_frequency:
          type: integer
          description: The repeat frequency of the campaign.
        no_of_occurences:
          type: integer
          description: The number of occurrences of the campaign.
        repeat_on_date_of_month:
          type: array
          items:
            type: integer
          description: |
            The dates of the month on which the campaign should be repeated.
            
            Example: [5, 25] to send on the 5th and 25th of each month.
        repeat_on_days_of_week:
          type: array
          items:
            type: string
            enum:
              - MONDAY
              - TUESDAY
              - WEDNESDAY
              - THURSDAY
              - FRIDAY
              - SATURDAY
              - SUNDAY
          description: The days of the week on which the campaign should repeat.
        repeat_on_days_of_week_for_month:
          type: array
          items:
            type: object
            properties:
              week_granularity:
                type: string
                enum:
                  - FIRST
                  - SECOND
                  - THIRD
                  - FOURTH
                  - LAST
              repeat_on_days_of_week:
                type: array
                items:
                  type: string
                  enum:
                    - MONDAY
                    - TUESDAY
                    - WEDNESDAY
                    - THURSDAY
                    - FRIDAY
                    - SATURDAY
                    - SUNDAY
          description: Configuration for repeating on specific weeks of the month.

    BTSDetails:
      type: object
      description: |
        Best Time to Send (BTS) configuration.
        
        BTS provides a prescriptive time slot to send a campaign to increase the chance of user interaction.
      properties:
        send_in_bts:
          type: boolean
          description: Whether to send the campaign at the best time.
        if_user_bts_is_not_available:
          type: string
          description: When to send the campaign if the user's best time is not available.
        if_user_bts_outside_time_window:
          type: string
          description: When to send the campaign if the user's best time is outside the time window.
        window_end_time:
          type: string
          description: The window end time.
          example: "6:43 am"

    UserTimezoneDetails:
      type: object
      description: Configuration for sending in the user's timezone.
      properties:
        send_in_user_timezone:
          type: boolean
          description: Whether to send the campaign on a specific date and time within the user's timezone.
        send_if_user_timezone_has_passed:
          type: boolean
          description: Whether to send the campaign if the user's timezone has passed.

    # ==================== Push Delivery Controls ====================
    PushDeliveryControls:
      type: object
      description: Controls for Push campaign delivery behavior.
      properties:
        bypass_dnd:
          type: boolean
          description: |
            Whether to bypass Do Not Disturb settings.
            
            Required for event-triggered campaigns.
        campaign_throttle_rpm:
          type: integer
          description: |
            The campaign throttle in requests per minute.
            
            Not applicable for device-triggered, location-triggered, and event-triggered campaigns.
          example: 50000
        count_for_frequency_capping:
          type: boolean
          description: Whether to count this campaign for frequency capping.
        ignore_frequency_capping:
          type: boolean
          description: Whether to ignore frequency capping for this campaign.
        minimum_delay_between_two_notification_in_hour:
          type: integer
          description: |
            Minimum delay between two notifications in hours.
            
            Applies to event-triggered and device-triggered campaigns.
        max_time_to_show_message_of_same_camapign:
          type: string
          description: |
            Maximum duration (in hours) that a message from this campaign will be displayed to a user.
            
            Applicable for device-triggered campaigns.
        expiry_time_of_sync_data_in_hour:
          type: string
          description: |
            Duration (in hours) after which synced campaign data will expire if trigger condition is not met.
            
            Applicable for device-triggered campaigns.
        send_message_in_offline_mode:
          type: boolean
          description: |
            Whether to store and deliver the message when the device is offline.
            
            Applicable for device-triggered campaigns.
        send_limit_value:
          type: string
          description: |
            Maximum number of times a user can receive this campaign within the specified time granularity.
            
            Applicable for location-triggered campaigns.
        send_limit_granularity_in_hours:
          type: string
          description: |
            Time window (in hours) during which the send_limit_value is enforced.
            
            Applicable for location-triggered campaigns.

    # ==================== Email Delivery Controls ====================
    EmailDeliveryControls:
      type: object
      description: Controls for Email campaign delivery behavior.
      properties:
        bypass_dnd:
          type: boolean
          description: Whether to bypass Do Not Disturb settings.
        campaign_throttle_rpm:
          type: integer
          description: The campaign throttle in requests per minute.
          example: 50000
        count_for_frequency_capping:
          type: boolean
          description: Whether to count this campaign for frequency capping.
        ignore_frequency_capping:
          type: boolean
          description: Whether to ignore frequency capping for this campaign.
        minimum_delay_between_two_notification_in_hour:
          type: integer
          description: Minimum delay between two notifications in hours.

    # ==================== Advanced Details ====================
    AdvancedDetails:
      type: object
      description: Advanced campaign settings.
      properties:
        expiration_settings:
          type: object
          properties:
            expire_notification_after_value:
              type: integer
              description: The numeric value for the notification expiration time.
            expire_notification_after_type:
              type: string
              enum:
                - HOUR
                - DAY
              description: The time unit for notification expiration.
            remove_from_inbox_after_value:
              type: integer
              description: The numeric value for when to remove the message from the inbox.
            remove_from_inbox_after_type:
              type: string
              enum:
                - DAY
              description: The time unit for removing the message from the inbox.
        platform_level_priority:
          type: object
          properties:
            android_specific_priority:
              type: object
              properties:
                send_with_priority:
                  type: boolean
                  description: Whether to send with priority.
            ios_specific_priority:
              type: object
              properties:
                apns_priority:
                  type: string
                  enum:
                    - "1"
                    - "5"
                    - "10"
                  description: The priority of notification delivery for APNS.
                interruption_level:
                  type: string
                  enum:
                    - Passive
                    - Active
                    - Time sensitive
                    - Critical
                  description: The interruption level for iOS notifications.
                relevance_score:
                  type: number
                  enum:
                    - 0
                    - 0.5
                    - 1
                  description: The relevance score for iOS notifications.

    # ==================== Conversion Goal Details ====================
    ConversionGoalDetails:
      type: object
      description: Configuration for tracking campaign conversion goals.
      properties:
        attribution_window_in_hours:
          type: integer
          description: The attribution window in hours.
          example: 36
        goals:
          type: array
          items:
            $ref: '#/components/schemas/Goal'
          description: List of conversion goals to track.

    Goal:
      type: object
      description: A single conversion goal configuration.
      properties:
        goal_name:
          type: string
          description: The name of the goal.
          example: "Goal 1"
        goal_event_name:
          type: string
          description: The event name associated with this goal.
        goal_event_attribute:
          $ref: '#/components/schemas/GoalEventAttribute'
        is_primary_goal:
          type: boolean
          description: Whether this is the primary goal.
        revenue_attribute:
          type: string
          description: The revenue attribute to track.
        revenue_currency:
          type: string
          description: The currency for revenue tracking.

    GoalEventAttribute:
      type: object
      description: Attributes associated with the conversion goal event.
      properties:
        name:
          type: string
          description: The name of the goal event attribute.
        condition:
          type: string
          description: The condition used while creating the goal (e.g., "is", "contains", "between").
        data_type:
          type: string
          enum:
            - STRING
            - DOUBLE
            - BOOL
            - NUMBER
            - GEOPOINT
            - DATETIME
            - ARRAY_DOUBLE
            - ARRAY_STRING
            - OBJECT
            - ARRAY_OBJECT
          description: The data type of the attribute.
        value:
          type: string
          description: |
            The value of the goal event attribute.
            Supported data types: STRING, DOUBLE, BOOL, NUMBER, GEOPOINT, DATETIME, ARRAY_DOUBLE, ARRAY_STRING.
        value1:
          type: string
          description: |
            A secondary value, used for conditions like 'between'.
            Supported data types: STRING, DOUBLE, BOOL, NUMBER, GEOPOINT, DATETIME, ARRAY_DOUBLE, ARRAY_STRING.
        negate:
          type: boolean
          description: Whether to negate the filter condition.
        value_type:
          type: string
          description: The type of value being filtered.
        array_filter_type:
          type: string
          description: The logical filter type for array attributes.
        filters:
          type: array
          description: A list of sub-filters used when data_type is OBJECT or ARRAY_OBJECT.
          items:
            type: object
        is_case_sensitive:
          type: boolean
          description: Whether the goal event attribute is case-sensitive.

    # ==================== Control Group Details ====================
    ControlGroupDetails:
      type: object
      description: Configuration for control groups.
      properties:
        is_campaign_control_group_enabled:
          type: boolean
          description: Whether the campaign control group is enabled.
        campaign_control_group_percentage:
          type: integer
          description: |
            The percentage of users added to the exclusion list.
            
            **Required** if is_campaign_control_group_enabled is true.
          minimum: 0
          maximum: 100
        is_global_control_group_enabled:
          type: boolean
          description: Whether the global control group is enabled.

    # ==================== UTM Parameters ====================
    UTMParams:
      type: object
      description: UTM parameters for tracking campaign performance.
      required:
        - utm_source
        - utm_medium
      properties:
        utm_source:
          type: string
          description: |
            The source of the traffic (e.g., YouTube, Instagram, Google).
            
            **Required** when using UTM parameters.
          example: "google"
        utm_medium:
          type: string
          description: |
            The channel type (e.g., Push, SMS, Email).
            
            **Required** when using UTM parameters.
          example: "email"
        utm_campaign:
          type: string
          description: The name of the campaign (e.g., Newyear, Bigbillionday).
          example: "summer_sale"
        utm_term:
          type: string
          description: Search terms for paid traffic (e.g., Mobile+sale).
        utm_content:
          type: string
          description: The content element that differentiates links (e.g., banner, video).
        utm_custom:
          type: string
          description: Custom UTM parameter (maximum of 5 custom parameters).

    # ==================== Connector ====================
    Connector:
      type: object
      description: Email connector configuration for sending email campaigns.
      required:
        - connector_type
        - connector_name
      properties:
        connector_type:
          type: string
          description: The type of connector service (e.g., SENDGRID, AWS SES, etc.).
          example: "SENDGRID"
        connector_name:
          type: string
          description: The name of the connector configuration.
          example: "default"

    # ==================== Campaign Audience Limit ====================
    CampaignAudienceLimit:
      type: object
      description: Configuration for limiting campaign audience.
      properties:
        limit:
          type: integer
          description: |
            The maximum number of times an audience can be included or targeted within the campaign.
        metrics:
          type: string
          description: |
            The type of measurement being tracked (e.g., impressions, clicks, conversions).
        frequency:
          type: string
          description: |
            How often the limit and metrics are applied (e.g., daily, weekly, monthly).

    # ==================== Response Schemas ====================
    CampaignCreateSuccessResponse:
      type: object
      properties:
        campaign_id:
          type: string
          description: The unique ID of the newly created campaign. Store this for future reference.
          example: "camp_12345abc"

    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: The error code (e.g., "400 Bad Request").
            message:
              type: string
              description: Description of why the request failed.
            target:
              type: string
              description: The target of the error.
            details:
              type: array
              items:
                type: object
                properties:
                  target:
                    type: string
                  message:
                    type: string
            request_id:
              type: string
              description: The request ID associated with this error.

  responses:
    NoContent:
      description: |
        Campaign updated successfully. The server successfully processed the request but is not returning any content.
    
    BadRequest:
      description: Bad Request - Missing or invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: "400 Bad Request"
              message: "request_id key is mandatory field"
              target: "request_id"
              details:
                - target: "request_id"
                  message: "request_id key is mandatory field"
              request_id: "11"
    
    Unauthorized:
      description: Authentication Failure - Invalid or missing authentication credentials
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: "401 Authentication error"
              message: "Authentication required"
              details:
                - code: "InvalidValue"
                  target: "APP_SECRET_KEY"
                  message:
                    - code: "InvalidValue"
                      target: "APP_SECRET_KEY"
                      message: "Invalid APP_SECRET_KEY is provided."
              request_id: ""
    
    RateLimitExceeded:
      description: Rate Limit Breach - Too many requests
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: "429 conflict"
              message: "rate_limit"
              target: ""
              details:
                - target: "rate_limit"
                  message: "Rate limiting breached"
              request_id: "3UXNNGsqV"
    
    InternalServerError:
      description: Internal Server Error - Unexpected system error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: "500 Internal Server Error"
              message: "Something went wrong. Please contact Moengage team"
              target: "string"
              details:
                - message: "Expecting value: line 1 column 1 (char 0)"
                  target: ""

paths:
  /campaigns:
    post:
      operationId: create_campaign
      summary: Create Campaign
      description: |
        This API creates a new Push or Email campaign in MoEngage with specified content, audience, and delivery settings.   
      x-mint:
        content: |       
          
          #### Rate Limits

          | Rate Limit Name | Rate Limit |
          | :--- | :--- |
          | Create campaign per minute | The total number of create campaign requests per minute per client allowed is 5. |
          | Create campaign per hour | The total number of create campaign requests per hour per client allowed is 25. |
          | Create campaign per day | The total number of create campaign requests per day per client allowed is 100. |  

          ### Campaign Creation Limits

          You can create 5 campaigns per minute, 25 campaigns per hour, and 100 campaigns per day.

          <Note>
           **Notes**
           * Higher limit (Total Calls): The system permits a higher volume of total API calls (for example, 120 calls) to accommodate potential failures or retries.
           * Minimum limit (Campaign Creation Limits): The system maintains a stricter quota for actual successful creations (100 campaigns per day).
              
              Example: If a client submits 120 requests and 20 fail, they successfully generate exactly 100 campaigns. Because the system applies the most restrictive threshold, the 100 successful operations trigger the quota limit, and the system issues a rate limit breach warning regardless of the total API calls made.
           * Breaching the limits will reject the request.
           * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.
          </Note>           
          
      tags:
        - Create Campaigns
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
        - name: MOE-PROJECT-CODE
          in: header
          schema:
            type: string
          description: |
            This is the project ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **Portfolio** > **Project ID**. **Note**: This parameter is mandatory for workspaces with the [Portfolio](https://www.moengage.com/docs/user-guide/settings/account/portfolio/portfolio) feature enabled.
          example: 'YOUR_PROJECT_ID_XXXX'
      requestBody:
        description: >-
          You can configure campaign content, audience, and scheduling details.
          
          **Note:** 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/CampaignCreateRequest'
            examples:
              push_one_time_android_ios:
                summary: Push - One-Time (Android & iOS)
                value:
                  request_id: "push_req_12345"
                  channel: "PUSH"
                  campaign_delivery_type: "ONE_TIME"
                  created_by: "john.doe@example.com"
                  basic_details:
                    name: "Summer Sale Push"
                    tags: ["activation", "sale"]
                    platforms: ["ANDROID", "IOS"]
                    platform_specific_details:
                      android:
                        push_amp_plus_enabled: true
                      ios:
                        send_to_all_eligible_device: true
                        exclude_provisional_push_devices: false
                        send_to_only_provisional_push_enabled_devices: false
                  campaign_content:
                    content:
                      push:
                        android:
                          template_type: "BASIC"
                          basic_details:
                            notification_channel: "general"
                            title: "50% Off Summer Sale!"
                            message: "Dont miss out on our biggest sale"
                            default_click_action: "DEEPLINKING"
                            default_click_action_value: "https://example.com/sale"
                            key_value_pairs:
                              - key: "promo_code"
                                value: "SUMMER50"
                        ios:
                          template_type: "BASIC"
                          basic_details:
                            title: "50% Off Summer Sale!"
                            message: "Dont miss out on our biggest sale"
                            default_click_action: "DEEPLINKING"
                            default_click_action_value: "https://example.com/sale"
                  segmentation_details:
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - filter_type: "user_attributes"
                          data_type: "string"
                          name: "uid"
                          operator: "exists"
                  scheduling_details:
                    delivery_type: "ASAP"
                  delivery_controls:
                    campaign_throttle_rpm: 50000
                    ignore_frequency_capping: false
              email_one_time_promotional:
                summary: Email - One-Time Promotional
                value:
                  request_id: "email_req_12345"
                  channel: "EMAIL"
                  campaign_delivery_type: "ONE_TIME"
                  created_by: "john.doe@example.com"
                  basic_details:
                    name: "Summer Sale Email"
                    content_type: "PROMOTIONAL"
                    subscription_category: "marketing"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                    tags: ["summer", "sale"]
                  connector:
                    connector_type: "SENDGRID"
                    connector_name: "default"
                  campaign_content:
                    content:
                      email:
                        subject: "Exclusive Summer Sale - 50% Off!"
                        preview_text: "Limited time offer on all products"
                        sender_name: "MoEngage Store"
                        from_address: "noreply@example.com"
                        reply_to_address: "support@example.com"
                        html_content: "<!DOCTYPE html><html><body><h1>Summer Sale</h1><p>Get 50% off on all items!</p></body></html>"
                        link_branding_domain: "yourbrand.com"
                        deep_link_domain: "deeplink.yourbrand.com"
                  segmentation_details:
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - filter_type: "user_attributes"
                          data_type: "string"
                          name: "u_em"
                          operator: "exists"
                  scheduling_details:
                    delivery_type: "ASAP"
                  delivery_controls:
                    campaign_throttle_rpm: 50000
                    ignore_frequency_capping: false
              email_with_gmail_annotations_deal_card:
                summary: Email - Gmail Annotations Deal Card (IST +05:30)
                value:
                  request_id: "{{request_id}}"
                  channel: "EMAIL"
                  campaign_delivery_type: "ONE_TIME"
                  created_by: "{{created_by}}"
                  basic_details:
                    name: "Exclusive Deal Email"
                    content_type: "PROMOTIONAL"
                    subscription_category: "{{subscription_category}}"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                    send_only_double_opt_in_users: true
                    deduplication_attribute: "{{deduplication_attribute}}"
                    tags: []
                  connector:
                    connector_type: "{{connector_type}}"
                    connector_name: "{{connector_name}}"
                  campaign_content:
                    content:
                      email:
                        subject: "Exclusive Deal Just for You"
                        preview_text: "Save big with our limited-time offer"
                        sender_name: "Your Brand"
                        from_address: "{{from_address}}"
                        reply_to_address: "{{reply_to_address}}"
                        html_content: "<!DOCTYPE html><html><body><p>Deal!</p></body></html>"
                        gmail_annotations:
                          send_email_if_personalization_fails: true
                          sender_logo: "https://example.com/logo.png"
                          sender_logo_type: "image_url"
                          deal_card:
                            description: "Get 20% off on all orders above $50"
                            discount_code: "SAVE20"
                            availability_starts: "2026-06-01T00:00:00+05:30"
                            availability_ends: "2026-06-30T23:59:59+05:30"
                  segmentation_details:
                    is_all_user_campaign: false
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - data_type: "string"
                          category: "Tracked Custom Attribute"
                          name: "u_em"
                          filter_type: "user_attributes"
                          case_sensitive: false
                          operator: "exists"
                          negate: false
                  scheduling_details:
                    delivery_type: "ASAP"
                  delivery_controls:
                    bypass_dnd: false
                    ignore_frequency_capping: false
                    count_for_frequency_capping: false
                    campaign_throttle_rpm: 3000
              email_with_gmail_annotations_product_carousel_manual:
                summary: Email - Gmail Annotations Product Carousel (Manual)
                value:
                  request_id: "{{request_id}}"
                  channel: "EMAIL"
                  campaign_delivery_type: "ONE_TIME"
                  created_by: "{{created_by}}"
                  basic_details:
                    name: "Featured Products Email"
                    content_type: "PROMOTIONAL"
                    subscription_category: "{{subscription_category}}"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                    send_only_double_opt_in_users: true
                    deduplication_attribute: "{{deduplication_attribute}}"
                    tags: []
                  connector:
                    connector_type: "{{connector_type}}"
                    connector_name: "{{connector_name}}"
                  campaign_content:
                    content:
                      email:
                        subject: "Featured Products This Week"
                        preview_text: "Discover our latest deals"
                        sender_name: "Your Brand"
                        from_address: "{{from_address}}"
                        reply_to_address: "{{reply_to_address}}"
                        html_content: "<!DOCTYPE html><html><body><p>Shop now!</p></body></html>"
                        gmail_annotations:
                          send_email_if_personalization_fails: true
                          sender_logo: "https://example.com/logo.png"
                          sender_logo_type: "image_url"
                          product_carousel:
                            type: "MANUAL"
                            manual_data:
                              currency: "USD"
                              products:
                                - id: "prod-001"
                                  headline: "Wireless Headphones"
                                  original_price: "199.99"
                                  discount_value: "30"
                                  discount_type: "PERCENT"
                                  promo_url: "https://example.com/products/prod-001"
                                  product_image: "https://example.com/images/prod-001.png"
                                - id: "prod-002"
                                  headline: "Smart Watch"
                                  original_price: "299.99"
                                  discount_value: "50"
                                  discount_type: "VALUE"
                                  promo_url: "https://example.com/products/prod-002"
                                  product_image: "https://example.com/images/prod-002.png"
                  segmentation_details:
                    is_all_user_campaign: false
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - data_type: "string"
                          category: "Tracked Custom Attribute"
                          name: "u_em"
                          filter_type: "user_attributes"
                          case_sensitive: false
                          operator: "exists"
                          negate: false
                  scheduling_details:
                    delivery_type: "ASAP"
                  delivery_controls:
                    bypass_dnd: false
                    ignore_frequency_capping: false
                    count_for_frequency_capping: false
                    campaign_throttle_rpm: 3000
              email_with_gmail_annotations_product_carousel_product_set:
                summary: Email - Gmail Annotations Product Carousel (Product Set)
                value:
                  request_id: "{{request_id}}"
                  channel: "EMAIL"
                  campaign_delivery_type: "ONE_TIME"
                  created_by: "{{created_by}}"
                  basic_details:
                    name: "Recommended For You Email"
                    content_type: "PROMOTIONAL"
                    subscription_category: "{{subscription_category}}"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                    send_only_double_opt_in_users: true
                    deduplication_attribute: "{{deduplication_attribute}}"
                    tags: []
                  connector:
                    connector_type: "{{connector_type}}"
                    connector_name: "{{connector_name}}"
                  campaign_content:
                    content:
                      email:
                        subject: "Picks Curated For You"
                        preview_text: "Personalized recommendations"
                        sender_name: "Your Brand"
                        from_address: "{{from_address}}"
                        reply_to_address: "{{reply_to_address}}"
                        html_content: "<!DOCTYPE html><html><body><p>Shop now!</p></body></html>"
                        gmail_annotations:
                          send_email_if_personalization_fails: true
                          sender_logo: "https://example.com/logo.png"
                          sender_logo_type: "image_url"
                          product_carousel:
                            type: "PRODUCT_SET"
                            product_set_data:
                              product_set: "product_set_12345"
                              image_url: "https://example.com/images/fallback.png"
                              headline: "Recommended For You"
                              promo_url: "https://example.com/shop"
                              product_count: 3
                  segmentation_details:
                    is_all_user_campaign: false
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - data_type: "string"
                          category: "Tracked Custom Attribute"
                          name: "u_em"
                          filter_type: "user_attributes"
                          case_sensitive: false
                          operator: "exists"
                          negate: false
                  scheduling_details:
                    delivery_type: "ASAP"
                  delivery_controls:
                    bypass_dnd: false
                    ignore_frequency_capping: false
                    count_for_frequency_capping: false
                    campaign_throttle_rpm: 3000
              push_event_triggered:
                summary: Push - Event Triggered
                value:
                  request_id: "push_event_12345"
                  channel: "PUSH"
                  campaign_delivery_type: "EVENT_TRIGGERED"
                  created_by: "john.doe@example.com"
                  basic_details:
                    name: "Cart Abandonment Push"
                    platforms: ["ANDROID", "IOS"]
                    platform_specific_details:
                      android:
                        push_amp_plus_enabled: true
                      ios:
                        send_to_all_eligible_device: true
                        exclude_provisional_push_devices: false
                        send_to_only_provisional_push_enabled_devices: false
                  trigger_condition:
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - filter_type: "actions"
                          action_name: "cart_abandoned"
                          execution:
                            type: "atleast"
                            count: 1
                          executed: true
                          attributes:
                            filter_operator: "and"
                            filters: []
                    trigger_delay_type: "DELAY"
                    trigger_delay_value: 1
                    trigger_delay_granularity: "HOURS"
                    trigger_relation: "AFTER"
                  campaign_content:
                    content:
                      push:
                        android:
                          template_type: "BASIC"
                          basic_details:
                            notification_channel: "general"
                            title: "Complete your purchase"
                            message: "Items in your cart are waiting"
                            default_click_action: "DEEPLINKING"
                            default_click_action_value: "myapp://cart"
                  segmentation_details:
                    included_filters:
                      filter_operator: "and"
                      filters:
                        - filter_type: "user_attributes"
                          data_type: "string"
                          name: "uid"
                          operator: "exists"
                  scheduling_details:
                    delivery_type: "AT_FIXED_TIME"
                    start_time: "2024-12-01T10:00:00"
                    expiry_time: "2024-12-31T23:59:59"
                  delivery_controls:
                    bypass_dnd: false
                    ignore_frequency_capping: false
      responses:
        '201':
          description: Campaign created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignCreateSuccessResponse'
              example:
                campaign_id: "camp_abc123xyz"
        '400':
          description: Bad Request - Missing or invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missing_request_id:
                  summary: Missing request_id
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "request_id key is mandatory field"
                      target: "request_id"
                      details:
                        - target: "request_id"
                          message: "request_id key is mandatory field"
                      request_id: "11"
                ProjectCodeError:
                  summary: Missing Project Code
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "MOE-PROJECT-CODE header missing in request"
                      target: "MOE-PROJECT-CODE"
                      details:
                         target: "MOE-PROJECT-CODE"
                         message: "MOE-PROJECT-CODE header missing in request"
                      request_id: "tb6bUhTAH0"
                InvalidProjectCode:
                  summary: Invalid Project Code
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "Invalid MOE-PROJECT-CODE received in request"
                      target: "MOE-PROJECT-CODE"
                      details:
                        - target: "MOE-PROJECT-CODE"
                          message: "Invalid MOE-PROJECT-CODE received in request"
                      request_id: "qTmKEBCUZo"
                deduplication_attribute_invalid_type:
                  summary: deduplication_attribute - invalid type
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "deduplication_attribute - Invalid value passed. Expected type: string, but got: int."
                      target: "basic_details"
                      details:
                        - target: "basic_details.deduplication_attribute"
                          message: "deduplication_attribute - Invalid value passed. Expected type: string, but got: int."
                send_only_double_opt_in_users_invalid_type:
                  summary: send_only_double_opt_in_users - invalid type
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "send_only_double_opt_in_users - Invalid value passed. Expected type: boolean, but got: string."
                      target: "basic_details"
                      details:
                        - target: "basic_details.send_only_double_opt_in_users"
                          message: "send_only_double_opt_in_users - Invalid value passed. Expected type: boolean, but got: string."
                gmail_annotations_on_transactional:
                  summary: gmail_annotations used on TRANSACTIONAL campaign
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "gmail_annotations is not supported for TRANSACTIONAL content type. It is only supported for PROMOTIONAL campaigns."
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations"
                          message: "gmail_annotations is not supported for TRANSACTIONAL content type. It is only supported for PROMOTIONAL campaigns."
                gmail_annotations_missing_sender_logo:
                  summary: sender_logo missing when gmail_annotations is present
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "sender_logo is required when gmail_annotations is specified"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.sender_logo"
                          message: "sender_logo is required when gmail_annotations is specified"
                gmail_annotations_invalid_sender_logo:
                  summary: sender_logo is not a valid HTTPS URL
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "sender_logo must be a valid https URL"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.sender_logo"
                          message: "sender_logo must be a valid https URL"
                deal_card_missing_field:
                  summary: Required deal_card field missing
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "availability_starts is required when deal_card is specified"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.deal_card.availability_starts"
                          message: "availability_starts is required when deal_card is specified"
                deal_card_invalid_end_time:
                  summary: availability_ends less than 1 hour after availability_starts
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "End date and time must be a minimum of one hour later than the start date and time"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.deal_card"
                          message: "End date and time must be a minimum of one hour later than the start date and time"
                product_carousel_minimum_products:
                  summary: Product carousel has fewer than 2 products
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "Product carousel requires a minimum of 2 products"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel"
                          message: "Product carousel requires a minimum of 2 products"
                product_set_product_count_exceeds_maximum:
                  summary: product_count exceeds maximum of 9
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "product_count must be between 2 and 9"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.product_set_data"
                          message: "product_count must be between 2 and 9"
                product_carousel_invalid_original_price:
                  summary: Manual product has invalid original_price
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "original_price must be a valid number"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.manual_data.products[0].original_price"
                          message: "original_price must be a valid number"
                product_carousel_invalid_discount_value:
                  summary: Manual product has invalid discount_value
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "discount_value must be a valid number"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.manual_data.products[0].discount_value"
                          message: "discount_value must be a valid number"
                product_carousel_invalid_promo_url:
                  summary: Manual product has invalid promo_url
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "promo_url must be a valid https URL"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.manual_data.products[0].promo_url"
                          message: "promo_url must be a valid https URL"
                product_carousel_empty_product_image:
                  summary: Manual product has empty product_image
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "product_image (Image URL) cannot be empty"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.manual_data.products[0].product_image"
                          message: "product_image (Image URL) cannot be empty"
                product_carousel_invalid_product_image_url:
                  summary: Manual product has invalid product_image URL
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "product_image must be a valid https URL"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.manual_data.products[0].product_image"
                          message: "product_image must be a valid https URL"
                product_set_not_found:
                  summary: Product set ID does not exist in the workspace
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "product_set not found for the given workspace"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel.product_set_data"
                          message: "product_set not found for the given workspace"
                product_sets_feature_not_enabled:
                  summary: Product Sets feature is not enabled for the workspace
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "Product Sets is not enabled for this workspace"
                      target: "campaign_content.content"
                      details:
                        - target: "gmail_annotations.product_carousel"
                          message: "Product Sets is not enabled for this workspace"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /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>
          **Differences in V5**

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

          See [Update Campaign (V5)](/api/update-campaigns/update-campaign-v5).
          </Note>

          <Warning>
          **Update Restrictions**
        
          You cannot update campaigns when in **Stopped** or **Archived** state.

          For **Scheduled Campaigns**
          - You can edit all fields **except scheduling type** for One-Time campaigns.
          - You can edit all fields **except scheduling type** for Periodic/Event-Triggered campaigns if no instance has been sent yet.
        
          For **Active Campaigns**, you cannot edit the following fields:
          - Trigger Condition
          - Segmentation Details
          - Conversion Goal Details
          - Scheduling Type
          - Scheduling Start Date

          For **Event-Triggered campaigns**, updated content is cached and takes up to 30 minutes to take effect.
          </Warning>

          #### 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 will consider the calculation based on the last hour and last 24 hrs respectively.
          </Note>
        
      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'
      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/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'
  
  /campaigns/search:
    post:
      operationId: search_campaigns
      summary: Search Campaigns
      description: |
        This API fetches a list of Push, Email, or SMS campaigns with all current fields and status. You can pass multiple filters to find specific campaigns.
      x-mint:
        content: |
    
          #### Search Capabilities
          - Filter by channel, delivery type, status, tags, name, ID, created by, created date
          - Include child campaigns (flow nodes, periodic children)
          - Include archived campaigns
          - Paginated results (max 15 per page)

          <Note>
          **Differences in V5**

          The V5 Search Campaigns API (`POST /v5/campaigns/search`) introduces the following behavioral changes:

          - **Single-campaign retrieval** is no longer handled by the search endpoint. Use `GET /v5/campaigns/{campaign_id}` instead.
          - The `campaign_fields.id` field (string) is renamed to `campaign_fields.ids` (array of strings) in V5.
          - The `campaign_fields.delivery_type` field is renamed to `campaign_fields.campaign_delivery_type` in V5. Sending the V1 field name returns zero results with no error.
          - `request_id` is required in V1. In V5, it is optional.
          - The response identifier field `campaign_id` is renamed to `id` in V5.

          For a full comparison, see [V1 vs. V5 Search Campaigns: Behavioral Differences](/api/campaigns/search-campaigns-v5-migration).
          </Note>
        

           #### Rate Limits

          | Rate Limit Name | Rate Limit |
          | :--- | :--- |
          | Search campaign per second | The total number of search campaign requests per second per client allowed is 10. |
          | Search campaign per minute | The total number of search campaign requests per minute per client allowed is 100. |
          | Search campaign per hour | The total number of search campaign requests per hour per client allowed is 6000. | 

          <Note>
            **Notes**
            * Breaching the limits will reject the request.
            * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.
          </Note>

      tags:
        - Get Campaign Details
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
      requestBody:
        description: |
          Provide the search criteria and pagination parameters for finding campaigns.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignSearchRequest'
            examples:
              search_by_channel_email:
                summary: Search by Channel (Email)
                value:
                  request_id: "search_req_12345"
                  campaign_fields:
                    channels: ["EMAIL"]
                  limit: 15
                  page: 1
              search_by_channel_push:
                summary: Search by Channel (Push)
                value:
                  request_id: "search_req_67890"
                  campaign_fields:
                    channels: ["PUSH"]
                  limit: 15
                  page: 1
              search_by_channel_sms:
                summary: Search by Channel (SMS)
                value:
                  request_id: "search_req_sms"
                  campaign_fields:
                    channels: ["SMS"]
                  limit: 15
                  page: 1
              search_by_delivery_type:
                summary: Search by Delivery Type
                value:
                  request_id: "search_req_periodic"
                  campaign_fields:
                    delivery_type: ["PERIODIC"]
                  limit: 15
                  page: 1
              search_by_created_date:
                summary: Search by Created Date
                value:
                  request_id: "search_req_date"
                  campaign_fields:
                    created_date:
                      from_date: "2024-06-16"
                      to_date: "2024-06-21"
                  limit: 10
                  page: 1
              search_by_campaign_name:
                summary: Search by Campaign Name
                value:
                  request_id: "search_req_name"
                  campaign_fields:
                    name: "Summer Sale Campaign"
                  limit: 5
                  page: 1
              search_by_campaign_id:
                summary: Search by Campaign ID
                value:
                  request_id: "search_req_id"
                  campaign_fields:
                    id: "camp_abc123xyz"
                  limit: 1
                  page: 1
              search_all_filters:
                summary: Search with Multiple Filters
                value:
                  request_id: "search_req_all"
                  campaign_fields:
                    channels: ["PUSH"]
                    created_by: ["john.doe@example.com"]
                    created_date:
                      from_date: "2024-01-01"
                      to_date: "2024-12-31"
                    delivery_type: ["ONE_TIME"]
                    status: ["ACTIVE"]
                    tags: ["summer", "sale"]
                  include_child_campaigns: true
                  include_archive_campaigns: false
                  limit: 15
                  page: 1
      responses:
        '200':
          description: Successfully retrieved campaign list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CampaignDetailsResponse'
              examples:
                email_campaign:
                  summary: Email Campaign Response
                  value:
                    - campaign_id: "camp_email_123"
                      status: "Active"
                      channel: "EMAIL"
                      campaign_delivery_type: "PERIODIC"
                      created_by: "john.doe@example.com"
                      created_at: "2024-07-04 08:00:54.847000"
                      sent_time: "2024-07-04 20:32:00"
                      basic_details:
                        name: "Weekly Newsletter"
                        content_type: "PROMOTIONAL"
                        subscription_category: "marketing"
                        tags: ["newsletter"]
                      connector:
                        connector_type: "SENDGRID"
                        connector_name: "default"
                push_campaign:
                  summary: Push Campaign Response
                  value:
                    - campaign_id: "camp_push_456"
                      status: "Scheduled"
                      channel: "PUSH"
                      campaign_delivery_type: "ONE_TIME"
                      created_by: "jane.smith@example.com"
                      created_at: "2025-06-26 12:09:20.209000"
                      sent_time: "2025-06-26 12:47:00.196000"
                      basic_details:
                        name: "Flash Sale Notification"
                        platforms: ["ANDROID", "IOS"]
                        tags: ["sale"]
                sms_campaign:
                  summary: SMS Campaign Response
                  value:
                    - campaign_id: "camp_sms_789"
                      status: "Active"
                      channel: "SMS"
                      campaign_delivery_type: "ONE_TIME"
                      created_by: "admin@example.com"
                      created_at: "2024-05-20 06:04:50.505000"
                      sent_time: "2024-05-20 06:04:50.505000"
                      sender_name: "MoEngage"
                      basic_details:
                        name: "Discount Code SMS"
                        tags: ["discount"]
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  
  /campaigns/test:
    post:
      operationId: test_campaign
      summary: Test Campaign
      description: |
        This API sends a test Push or Email campaign to specific users or identifiers before launching it to your entire audience. You can only test campaigns created via the API, not campaigns created through the MoEngage dashboard.
      x-mint:
        content: |
          #### Rate Limits

          | Rate  Limit Name | Rate Limit |
          | :--- | :--- |
          | Test campaign per second | The total number of test campaign requests per second per client allowed is 10. |
          | Test campaign per minute | The total number of test campaign requests per minute per client allowed is 100. |
          | Test campaign per hour | The total number of test campaign requests per hour per client allowed is 6000. | 

          <Note>
            **Notes**
            * Breaching the limits will reject the request.
            * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.
          </Note>

      tags:
        - Test Campaigns
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
        - name: MOE-PROJECT-CODE
          in: header
          schema:
            type: string
          description: |
            This is the project ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **Portfolio** > **Project ID**. **Note**: This parameter is mandatory for workspaces with the [Portfolio](https://www.moengage.com/docs/user-guide/settings/account/portfolio/portfolio) feature enabled.
          example: 'YOUR_PROJECT_ID_XXXX'
      requestBody:
        description: >-
          Test campaign configuration including content and target test users.

          **Note:** 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/CampaignTestRequest'
            examples:
              push_test_basic:
                summary: Push - Test with User ID
                value:
                  request_id: "test_push_123"
                  channel: "PUSH"
                  basic_details:
                    name: "Flash Sale Push Test"
                    platforms: ["ANDROID", "IOS"]
                    platform_specific_details:
                      android:
                        push_amp_plus_enabled: true
                      ios:
                        send_to_all_eligible_device: true
                        exclude_provisional_push_devices: false
                        send_to_only_provisional_push_enabled_devices: false
                  campaign_content:
                    content:
                      push:
                        android:
                          template_type: "BASIC"
                          basic_details:
                            notification_channel: "general"
                            title: "Test: Flash Sale!"
                            message: "Testing message content"
                            default_click_action: "DEEPLINKING"
                            default_click_action_value: "https://example.com/sale"
                        ios:
                          template_type: "BASIC"
                          basic_details:
                            title: "Test: Flash Sale!"
                            message: "Testing message content"
                            default_click_action: "DEEPLINKING"
                            default_click_action_value: "https://example.com/sale"
                  test_campaign_meta:
                    identifier: "USER_ATTRIBUTE_UNIQUE_ID"
                    identifier_values: ["user_12345"]
              email_test_with_personalization:
                summary: Email - Test with Personalization
                value:
                  request_id: "test_email_456"
                  channel: "EMAIL"
                  basic_details:
                    name: "Newsletter Test"
                    content_type: "PROMOTIONAL"
                    subscription_category: "marketing"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                  connector:
                    connector_type: "SENDGRID"
                    connector_name: "default"
                  campaign_content:
                    content:
                      email:
                        subject: "Test: Weekly Newsletter"
                        preview_text: "Testing email content"
                        sender_name: "MoEngage Store"
                        from_address: "noreply@example.com"
                        reply_to_address: "support@example.com"
                        html_content: "<!DOCTYPE html><html><body><p>Hi {{UserAttribute['First Name']}},</p><p>Testing personalized content</p></body></html>"
                  personalization_details:
                    user_attributes:
                      First Name: "John"
                      Last Name: "Doe"
                    event_attributes:
                      Campaign Name: "Test Campaign"
                  test_campaign_meta:
                    identifier: "EMAIL"
                    identifier_values: ["john.doe@example.com", "jane.smith@example.com"]
              email_test_locale_variation:
                summary: Email - Test with Locale & Variation
                value:
                  request_id: "test_email_locale"
                  channel: "EMAIL"
                  basic_details:
                    name: "Multi-locale Test"
                    content_type: "PROMOTIONAL"
                    subscription_category: "marketing"
                    user_attribute_identifier: "MOE_EMAIL_ID"
                  connector:
                    connector_type: "SENDGRID"
                    connector_name: "default"
                  campaign_content:
                    locales: ["en-US", "es-ES", "default"]
                    content:
                      "en-US":
                        variation_1:
                          email:
                            subject: "Test EN"
                            sender_name: "Store"
                            from_address: "noreply@example.com"
                            reply_to_address: "support@example.com"
                            html_content: "<html><body>English content</body></html>"
                  test_campaign_meta:
                    identifier: "ID"
                    identifier_values: ["user_001"]
                    locale_name: "en-US"
                    variation: "variation_1"
      responses:
        '200':
          description: Test campaign sent successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestCampaignSuccessResponse'
              examples:
                success:
                  summary: Successful Test
                  value:
                    data:
                      user_12345:
                        status: "success"
                    message: "Test campaign created successfully"
                partial_success:
                  summary: Partial Success
                  value:
                    data:
                      john.doe@example.com:
                        status: "success"
                      jane.smith@example.com:
                        status: "failed"
                        failure_reason: "User not found"
                    message: "Test campaign created successfully"
        '400':
          description: Bad Request - Missing or invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                ProjectCodeError:
                  summary: Missing Project Code
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "MOE-PROJECT-CODE header missing in request"
                      target: "MOE-PROJECT-CODE"
                      details:
                         target: "MOE-PROJECT-CODE"
                         message: "MOE-PROJECT-CODE header missing in request"
                      request_id: "tb6bUhTAH0"
                InvalidProjectCode:
                  summary: Invalid Project Code
                  value:
                    error:
                      code: "400 Bad Request"
                      message: "Invalid MOE-PROJECT-CODE received in request"
                      target: "MOE-PROJECT-CODE"
                      details:
                        - target: "MOE-PROJECT-CODE"
                          message: "Invalid MOE-PROJECT-CODE received in request"
                      request_id: "qTmKEBCUZo"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  
  /personalization/preview:
    post:
      operationId: personalized_preview
      summary: Personalized Preview
      description: |
        This API shows a preview of personalized content for a specific user before sending a Push, Email, or SMS campaign. This API retrieves personalized message content with all user/event attributes resolved. Use this API to validate your personalization logic and see exactly how content will appear to specific users before launching campaigns. 
      x-mint:
        content: |
        
          #### Personalization Support
          - User attributes
          - Event attributes
          - Custom templates
          - Content blocks
          - Content APIs
          - Product sets
        
          #### Rate Limit
          The rate limit is 10,000 requests per minute.
        
      tags:
        - Test Campaigns
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
        - name: data-compression
          in: header
          required: false
          description: |
            Whether to pass the payload in compressed format.
            
            Set to `true` to send compressed payload.
          schema:
            type: boolean
          example: false
      requestBody:
        description: Provide personalization preview request with content and user details.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonalizedPreviewRequest'
            examples:
              user_attribute_preview:
                summary: Preview with User Attributes
                value:
                  request_id: "preview_req_12345"
                  personalization_details:
                    channel: "EMAIL"
                    user_attributes:
                      Gender: "Female"
                      First Name: "Jane"
                  personalization_content:
                    payload:
                      email_html: "<!DOCTYPE html><html><body><p>Hi {{UserAttribute['First Name']}}, your gender is {{UserAttribute['Gender']}}</p></body></html>"
                  user_details:
                    identifier: "ID"
                    identifier_value: "USER_001"
              event_attribute_preview:
                summary: Preview with Event Attributes
                value:
                  request_id: "preview_req_event"
                  personalization_details:
                    event_name: "App_Opened"
                    channel: "EMAIL"
                    user_attributes:
                      First Name: "John"
                    event_attributes:
                      App_Version: "1.0.2"
                  personalization_content:
                    payload:
                      message: "Hi {{UserAttribute['First Name']}}, you're using version {{EventAttribute['App_Version']}}"
                  user_details:
                    identifier: "ID"
                    identifier_value: "JOHN012"
              custom_template_preview:
                summary: Preview with Custom Template
                value:
                  request_id: "preview_req_template"
                  personalization_details:
                    channel: "PUSH"
                    user_attributes:
                      First Name: "John"
                    event_attributes:
                      App Version: "34232"
                  personalization_content:
                    custom_template_data:
                      template_id: "5b7d04c6-8ddc-4957-80d9-c67266079609"
                      version: "1"
                  user_details:
                    identifier: "ID"
                    identifier_value: "JOHN012"
              content_block_preview:
                summary: Preview with Content Block
                value:
                  request_id: "preview_req_cb"
                  personalization_details:
                    channel: "SMS"
                    user_attributes:
                      First Name: "John Doe"
                  personalization_content:
                    payload:
                      content_block: "{{ContentBlock['simple_text_cb']}}"
                  user_details:
                    identifier: "ID"
                    identifier_value: "JOHN012"
              product_set_preview:
                summary: Preview with Product Set
                value:
                  request_id: "preview_req_products"
                  personalization_details:
                    channel: "SMS"
                  personalization_content:
                    payload:
                      product_set: "{% if ProductSet.test_prod%}{% for product in ProductSet.test_prod%}{{product.title}} {% endfor %}{% else %}MOE_NOT_SEND{% endif %}"
                  user_details:
                    identifier: "ID"
                    identifier_value: "JOHN012"
      responses:
        '200':
          description: Successfully retrieved personalized content preview
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonalizedPreviewResponse'
              examples:
                user_attribute_result:
                  summary: Personalized User Attributes
                  value:
                    personalized_content:
                      payload:
                        email_html: "<!DOCTYPE html><html><body><p>Hi Jane, your gender is Female</p></body></html>"
                event_attribute_result:
                  summary: Personalized Event Attributes
                  value:
                    personalized_content:
                      payload:
                        message: "Hi John, you're using version 1.0.2"
                custom_template_result:
                  summary: Custom Template Result
                  value:
                    personalized_content:
                      payload:
                        data:
                          - meta_info:
                              platform: ["ANDROID"]
                              template_id: "12356733"
                              template_name: "test_template"
                              channel: "PUSH"
                product_set_result:
                  summary: Product Set Result
                  value:
                    personalized_content:
                      payload:
                        product_set: "Brown Banana Chocolate Wine Honey Onion Mango Cookies Bread Toffee"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalServerError'
  
  /campaigns/meta:
    post:
      operationId: get_campaign_meta
      summary: "Get Campaign Meta (V1 — Legacy)"
      description: |
        This API retrieves campaign details and reachability information for scheduled campaigns.
      x-mint:
        content: |
          <Warning>
          **V1 endpoint**

          This page documents the V1 Get Campaign Meta endpoint. The V5 equivalent is available at [Get Campaign Meta (V5)](/api/get-campaign-details/get-campaign-meta). Both V1 and V5 use Basic Auth with a `MOE-APPKEY` header.
          </Warning>

          #### Supported Channels
          - EMAIL: Email campaigns
          - PUSH: Push notification campaigns
          - SMS: SMS campaigns
          - WHATSAPP: WhatsApp campaigns
          - FACEBOOK: Facebook campaigns
          - GOOGLE ADS: Google Ads campaigns
          - CONNECTORS: Connector-based campaigns
        
          #### Reachability Information
          - Available only for **scheduled** campaigns (one-time, business event-triggered, and event-triggered).
          - Provides estimated user count that will receive the campaign.
          - Calculated once daily and cached for 24 hours.
          - May vary due to app installations/uninstalls or subscription changes.
          - Reachability is an estimated value and may vary over time. It is calculated once per day and cached for 24 hours. Multiple API calls within the same day will return the cached value.
          
          #### Rate Limits

          | Rate Limit Name | Rate Limit |
          | :--- | :--- |
          | get campaign meta per second | The total number of get campaign meta requests per Second per client allowed is 10. |
          | get campaign meta per minute | The total number of get campaign meta requests per minute per client allowed is 100. |
          | get campaign meta per hour | The total number of get campaign meta requests per hour per client allowed is 6000. | 

            <Note>
              **Notes**
              * Breaching the limits will reject the request.
              * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.
              </Note>
      tags:
        - Get Campaign Details
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
      requestBody:
        description: |
          Provide the search criteria for retrieving campaign metadata and reachability information.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignMetaRequest'
            examples:
              meta_by_channel:
                summary: Get Meta by Channel
                value:
                  request_id: "meta_req_12345"
                  campaign_fields:
                    channels: ["EMAIL"]
                  limit: 15
                  page: 1
              meta_by_campaign_id:
                summary: Get Meta by Campaign ID
                value:
                  request_id: "meta_req_67890"
                  campaign_fields:
                    id: "camp_abc123xyz"
                  limit: 1
                  page: 1
              meta_scheduled_with_reachability:
                summary: Get Scheduled Campaign with Reachability
                value:
                  request_id: "meta_req_scheduled"
                  campaign_fields:
                    channels: ["SMS"]
                    status: ["SCHEDULED"]
                  limit: 10
                  page: 1
              meta_with_child_campaigns:
                summary: Get Meta with Child Campaigns
                value:
                  request_id: "meta_req_children"
                  campaign_fields:
                    delivery_type: ["PERIODIC"]
                  include_child_campaigns: true
                  limit: 15
                  page: 1
      responses:
        '200':
          description: Successfully retrieved campaign metadata
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CampaignMetaResponse'
              examples:
                email_campaign_meta:
                  summary: Email Campaign Meta
                  value:
                    - campaign_id: "camp_email_123"
                      channel: "EMAIL"
                      platform: []
                      created_by: "john.doe@example.com"
                      campaign_delivery_type: "ONE_TIME"
                      campaign_name: "Weekly Newsletter"
                      campaign_team: "Marketing"
                      campaign_tags: ["newsletter", "weekly"]
                      campaign_status: "Active"
                      campaign_start_time: "2024-11-18T05:50:00"
                sms_scheduled_with_reachability:
                  summary: SMS Scheduled with Reachability
                  value:
                    - campaign_id: "camp_sms_456"
                      channel: "SMS"
                      platform: []
                      created_by: "admin@example.com"
                      campaign_delivery_type: "ONE_TIME"
                      campaign_name: "Promo Code SMS"
                      campaign_team: "Sales"
                      campaign_tags: ["promo"]
                      campaign_status: "Scheduled"
                      campaign_start_time: "2024-11-28T12:18:00"
                      reachability_details:
                        count: 18182
                        last_updated_time: "2024-11-27T09:05:42.661000"
                push_campaign_meta:
                  summary: Push Campaign Meta
                  value:
                    - campaign_id: "camp_push_789"
                      channel: "PUSH"
                      platform: ["ANDROID", "IOS"]
                      created_by: "jane.smith@example.com"
                      campaign_delivery_type: "EVENT_TRIGGERED"
                      campaign_name: "Cart Abandonment"
                      campaign_team: "Retention"
                      campaign_tags: ["cart", "abandonment"]
                      campaign_status: "Active"
                      campaign_start_time: "2024-11-20T10:00:00"
                periodic_with_children:
                  summary: Periodic Campaign with Children
                  value:
                    - campaign_id: "camp_periodic_101"
                      channel: "EMAIL"
                      platform: []
                      created_by: "marketing@example.com"
                      campaign_delivery_type: "PERIODIC"
                      campaign_name: "Monthly Newsletter"
                      campaign_team: "Content"
                      campaign_tags: ["newsletter"]
                      campaign_status: "Active"
                      campaign_start_time: "2024-01-01T09:00:00"
                      total_child_campaigns: 12
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  
  /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>
          **Differences in V5**

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

          See [Update Campaign Status (V5)](/api/update-campaigns/update-campaign-status-v5).
          </Note>

          <Note>
            Currently, you can use this API to change the status of Email and Push campaigns. You can update the following statuses of the campaigns:
              - Stop a scheduled One-time campaign (Email and Push)
              - Pause and resume a running Periodic or Event-triggered Email campaign.
              - Pause and resume the following running Push campaigns:
                - Periodic
                - Event-triggered
                - Device-triggered
                - Location-triggered
          </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 statusper 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 will consider the calculation based on the last hour and last 24 hrs respectively.
            </Note>
        
      tags:
        - Update Campaigns
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
      requestBody:
        description: Send campaign status change request with action and campaign IDs.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignStatusChangeRequest'
            examples:
              pause_campaign:
                summary: Pause Campaign
                value:
                  request_id: "status_change_pause"
                  action: "PAUSE"
                  campaign_ids: ["camp_periodic_123"]
              resume_campaign:
                summary: Resume Campaign
                value:
                  request_id: "status_change_resume"
                  action: "RESUME"
                  campaign_ids: ["camp_periodic_123"]
              stop_campaign:
                summary: Stop Scheduled Campaign
                value:
                  request_id: "status_change_stop"
                  action: "STOP"
                  campaign_ids: ["camp_onetime_456"]
              batch_pause:
                summary: Pause Multiple Campaigns
                value:
                  request_id: "status_batch_pause"
                  action: "PAUSE"
                  campaign_ids: 
                    - "camp_periodic_001"
                    - "camp_periodic_002"
                    - "camp_event_003"
      responses:
        '200':
          description: |
            Campaign status changed successfully. No content returned.
            
            For a successful 200 response, the API does not return any content.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
  
  /campaigns/{parent_campaign_id}/executions:
    post:
      operationId: get_child_campaigns
      summary: Get Child Campaigns
      description: |
        This API retrieves child campaign execution details for Periodic or Business Event-triggered campaigns. Use this API to track execution history of recurring campaigns and monitor the performance of individual instances.
      x-mint:
        content: |
          <Warning>
          **Not available in V5**

          This endpoint is not yet available in V5. Use this V1 endpoint at `POST /core-services/v1/campaigns/{parent_campaign_id}/executions` until V5 support is added.
          </Warning>

          #### Information Retrieved
          - Child campaign IDs
          - Sent time for each execution
          - Status of each child campaign
          - Total number of times the parent campaign has been executed
          
          <Note>
          **Note**
          - Currently, you can use this API to get the child of Periodic and Business Event-triggered Email and Push campaigns.
          - You can only retrieve child campaigns for campaigns created via the [Create Campaign API](https://www.moengage.com/docs/api/create-campaigns/create-campaign).
          - Results are paginated with a maximum of 15 children per page.
          </Note>

          #### Rate Limits

          | Rate Limit Name | Rate Limit |
          | :--- | :--- |
          | get child campaign per second | The total number of get child campaigns requests per second per client allowed is 10. |
          | get child campaign per minute | The total number of get child campaigns requests per minute per client allowed is 100. |
          | get child campaign per hour | The total number of get child campaigns requests per hour per client allowed is 6000. | 

          <Note>
           **Notes**
           * Breaching the limits will reject the request.
           * Per hour and per day limits will consider the calculation based on the last hour and last 24 hrs respectively.
          </Note>

         
      tags:
        - Get Campaign Details
      parameters:
        - name: parent_campaign_id
          in: path
          required: true
          description: |
            The unique ID of the parent campaign (Periodic or Business Event-triggered).
            
            You can fetch the parent campaign ID using the Search Campaigns API.
          schema:
            type: string
          example: "camp_periodic_parent_123"
        - $ref: '#/components/parameters/MOE-APPKEY'
      requestBody:
        description: Provide pagination parameters for retrieving child campaign executions.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetChildCampaignsRequest'
            examples:
              get_periodic_children:
                summary: Get Periodic Campaign Children
                value:
                  request_id: "child_req_12345"
                  page: 1
                  limit: 15
              get_business_event_children:
                summary: Get Business Event Children
                value:
                  request_id: "child_req_67890"
                  page: 1
                  limit: 10
              get_second_page:
                summary: Get Second Page of Children
                value:
                  request_id: "child_req_page2"
                  page: 2
                  limit: 15
      responses:
        '200':
          description: Successfully retrieved child campaign execution details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChildCampaignsResponse'
              examples:
                periodic_executions:
                  summary: Periodic Campaign Executions
                  value:
                    executions:
                      - campaign_id: "camp_child_001"
                        sent_time: "2024-06-24T14:30:18.908000"
                        status: "Sent"
                      - campaign_id: "camp_child_002"
                        sent_time: "2024-06-24T15:27:45.971000"
                        status: "Sent"
                      - campaign_id: "camp_child_003"
                        sent_time: "2024-06-24T15:47:43.528000"
                        status: "Sent"
                      - campaign_id: "camp_child_004"
                        sent_time: "2024-06-24T15:54:26.254000"
                        status: "Sent"
                      - campaign_id: "camp_child_005"
                        sent_time: "2024-06-24T16:35:01.834000"
                        status: "Sending"
                    total_instances: 8
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /global-control-group/users:
    put:
      operationId: update_global_control_group
      summary: Update Global Control Group
      description: |
        This API adds or removes users from the Global Control Group (GCG) in MoEngage. Provide a publicly accessible CSV of user IDs and specify whether to add or remove those users.
      x-mint:
        content: |
          <Warning>
          **Not available in V5**

          This endpoint is not yet available in V5. Use this V1 endpoint at `PUT /core-services/v1/global-control-group/users` until V5 support is added.
          </Warning>

          #### Rate Limit
          The rate limit is 10 RPM.

          <Note>
          - One file-processing request must complete before the next API call is accepted.
          - Currently, only publicly accessible Amazon S3 URLs are supported for `file_url`.
          - The Global Control Group must already be initialized with the **Upload Users** option before this API can be used. This API does not support the **Random allocation** option.
          - When the GCG base is successfully updated, subsequent runs of existing campaigns use the updated list.
          - Once file processing is completed, an email is sent to the user identified by `updated_by` summarizing the number of users successfully processed, the number of users that failed, and the possible reasons.
          </Note>
      tags:
        - Update Campaigns
      parameters:
        - $ref: '#/components/parameters/MOE-APPKEY'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GlobalControlGroupRequest'
            examples:
              add_users:
                summary: Add Users
                value:
                  request_id: "{{request_id}}"
                  file_url: "https://example.csv"
                  action_type: "add"
                  updated_by: "john.doe@xyz.com"
              remove_users:
                summary: Remove Users
                value:
                  request_id: "{{request_id}}"
                  file_url: "https://example.csv"
                  action_type: "remove"
                  updated_by: "john.doe@xyz.com"
      responses:
        '204':
          description: No Content - The request was processed successfully. There is no response body.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          description: Internal Server Error - An unexpected error occurred while processing this request.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      title:
                        type: string
                        description: A short title for the error.
                      description:
                        type: string
                        description: A detailed, human-readable explanation of the error.
                      code:
                        type: string
                        description: Internal error code, if provided.
              example:
                error:
                  title: "Server Error"
                  description: "An unexpected error was encountered while processing this request. Please contact Moengage team"
                  code: "<code>"