openapi: 3.0.3
info:
  title: MoEngage Campaign Stats and Reports API
  description: |
    The Stats API allows you to fetch detailed campaign stats synchronized in real time. 
    The Campaign Report API allows you to download campaign reports for any specific date range.
  version: '1.0'
servers:
  - url: 'https://api-{dc}.moengage.com'
    description: MoEngage 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."
tags:
  - name: Stats
    description: Fetch detailed, real-time campaign statistics.
  - name: Campaign Reports
    description: Download campaign report files.
paths:
  /core-services/v1/campaign-stats:
    post:
      tags:
        - Stats
      summary: Get Campaign Stats
      description: |
        This API fetches data at the platform level and provides data for all types of campaigns.

      x-mint:
        content: |
            #### Rate Limit
            
            This API provides all version stats, and the call rate is limited to **100 API calls per minute** per workspace.
            <Info>
             - Make sure to pass the relevant Campaign IDs in the request to fetch stats for flow-linked campaigns.
             - Stats data is retained for the entire lifetime of a campaign, from its start date, there is no fixed retention cutoff. The 30-day limit applies only to the date range of a single API call, not to how far back you can query.
            </Info>
      operationId: getCampaignStats
      security:
        - basicAuth: []
      parameters:
        - name: MOE-APPKEY
          in: header
          required: true
          schema:
            type: string
          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)**.
          example: 'YOUR_WORKSPACE_ID_XXXX'
      requestBody:
        $ref: '#/components/requestBodies/CampaignStatsRequest'
      responses:
        '200':
          description: Successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignStatsResponse'
              examples:
                stats-response:
                  summary: Sample Response
                  value:
                    response_id: "string"
                    total_campaigns: 1
                    current_page: 1
                    total_pages: 1
                    data:
                      "66e933029ff25f3322d8279d":
                        - platforms:
                            android:
                              locales:
                                all_locales:
                                  variations:
                                    all_variations:
                                      performance_stats:
                                        attempted: 2
                                        sent: 2
                                        failed: 0
                                        impression: 2
                                        click: 4
                                        ctr: 200
                                        delivery_rate: 100
                                        sent_rate: 100
                                        failure_rate: 0
                                      conversion_goal_stats:
                                        "Goal 1":
                                          conversions: 0
                                          cvr: 0
                                          uplift: 0
                                      delivery_funnel:
                                        reachable_users_in_segment: 2
                                        segment_after_uninstall: 2
                                        after_fc: 2
                                        users_after_dup: 2
                                        sent: 2
                                        user_devices: 2
                                        impressions: 2
                                        active_device_token: 2
                                      failure_breakdown: {}
                                    campaign_control_group:
                                      conversion_goal_stats:
                                        "Goal 1":
                                          conversions: 0
                                          cvr: 0
                                          uplift: 0
                                      delivery_funnel:
                                        reachable_users_in_segment: 0
                                      failure_breakdown:
                                        user_removed_due_to_campaing_control_group: 1
                                    global_control_group:
                                      conversion_goal_stats:
                                        "Goal 1":
                                          conversions: 0
                                          cvr: 0
                                          uplift: 0
                                      delivery_funnel:
                                        reachable_users_in_segment: 0
                                      failure_breakdown:
                                        user_removed_due_to_global_control_group: 1
        '400':
          description: |
            **Bad request**
            Possible issues include duplicates, invalid data types, or missing mandatory attributes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseSimple'
              example:
                title: "Invalid Field Value"
                description: "app_key - Some of the field values are invalid: app_key : None"
                code: "wUcwPRZF"
        '401':
          description: |
            **Unauthorized**
            This response is returned upon unauthorized request. Provide appropriate authentication credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseSimple'
              example:
                title: "Authentication required"
                description: "Invalid identity information found."
                code: "wUcwPRZF"
        '403':
          description: |
            **Forbidden**
            This response is returned when our account does not have access to the campaign stats management features.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseSimple'
              example:
                title: "Forbidden Request"
                description: null
                code: "kmqLuuHM"
        '429':
          description: |
            **Too many requests**
            This response is returned when the number of requests per minute has exceeded the rate limit.
        '500':
          description: |
            **Internal server error**
            This response is returned when the system runs into an unexpected error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseSimple'
              example:
                title: "Server Error"
                description: "An unexpected error was encountered while processing this request. Please contact MoEngage Team"
                code: "jDTGSxjd"

  /campaign_reports/rest_api/{APP_ID}/{FILENAME}:
    get:
      tags:
        - Campaign Reports
      summary: Download Campaign Report
      description: |
        This API downloads campaign reports for any specific date range. You can fetch reports for one-time and periodic campaigns.
        
      x-mint:
        content: |
          #### Limits

          - **Expiry**: The generated reports will expire in **7 days** from the date of creation.
          - **Max Range**: You can generate reports for up to **90 days**.
          
          #### Generating the Signature
          A unique signature must be passed in the headers to verify the caller's authenticity. 
          
          The signature is `SHA256(Api_ID + "|" + FILENAME + "|" + SECRET_KEY)`.

          ```python
          # SAMPLE IMPLEMENTATION IN PYTHON
          from hashlib import sha256
          Api_ID = "YOUR-APP-ID"
          FILENAME = "Report_-_test_20210217.zip"
          SECRET_KEY = "YOUR-SECRET-KEY"
          Signature_Key = Api_ID + "|" + FILENAME + "|" + SECRET_KEY
          # Now Signature is hexdigest of sha256 of Signature_Key
          Signature = sha256(Signature_Key.encode('utf-8')).hexdigest()
          ```
      operationId: downloadCampaignReport
      security:
        - apiKeySignature: []
      parameters:
        - name: APP_ID
          in: path
          required: true
          schema:
            type: string
          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)**.
          example: 'YOUR-APP-ID'
        - name: FILENAME
          in: path
          required: true
          schema:
            type: string
          description: |
            The name of the report file to download. It is a combination of report name, generation date, and file format.
            Example: `Report_test_20210217.zip`
          example: 'Report_-_test_20210217.zip'
        - name: Signature
          in: header
          required: true
          schema:
            type: string
          description: 'A custom signature generated by SHA256(Api_ID + "|" + FILENAME + "|" + SECRET_KEY).'
          example: '80300f554f9dc88cdc7d64c6c06f4de580b27a2afcc396816d1ec3a8d1c09579'
      responses:
        '200':
          description: Successful API request automatically downloads the report file.
          content:
            application/gzip:
              schema:
                type: string
                format: binary
        '400':
          description: |
            **Bad Request**
            Reasons: Invalid Report file name, requested report is older than 7 days, or incorrect App Id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseCampaignReport'
        '401':
          description: 'Unauthorized. Invalid Signature or Signature Missing.'
          content:
            application/json:
              schema:
                type: object
                description: Empty body.

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).
    apiKeySignature:
      type: apiKey
      in: header
      name: Signature
      description: |
        Custom SHA256 Signature. Refer [here](/api/campaign-reports/download-campaign-report#generating-the-signature).

  requestBodies:
    CampaignStatsRequest:
      description: Request body to fetch campaign stats.
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CampaignStatsRequest'
          examples:
            with-campaign-ids:
              summary: With Campaign IDs
              value:
                request_id: "abc"
                campaign_ids:
                  - "6643773d4fe37fe7a10b718e"
                  - "6645fbae1101e4c6611b15c7"
                  - "67c1cfc8c1b46a5ad5022de7"
                start_date: "2024-12-22"
                end_date: "2024-12-23"
                attribution_type: "VIEW_THROUGH"
                metric_type: "TOTAL"
            without-campaign-ids:
              summary: Without Campaign IDs
              value:
                request_id: "abc"
                start_date: "2024-12-22"
                end_date: "2024-12-23"
                attribution_type: "VIEW_THROUGH"
                metric_type: "TOTAL"

  schemas:
    CampaignStatsRequest:
      type: object
      required:
        - request_id
        - start_date
        - end_date
        - attribution_type
        - metric_type
      properties:
        request_id:
          type: string
          description: This field shows the request ID created by a user. Helps to know the API calls made by the client.
        campaign_ids:
          type: array
          items:
            type: string
          description: This field shows the campaign IDs created, up to 10 max per call.
          maxItems: 10
        start_date:
          type: string
          format: date
          description: This field shows the start date of the campaign in YYYY-MM-DD format. This date is interpreted in your MoEngage account's app timezone.
          example: '2024-12-22'
        end_date:
          type: string
          format: date
          description: This field shows the campaign's end date in YYYY-MM-DD format. The days between the start and end dates should not exceed 30 days. This date is interpreted in your MoEngage account's app timezone.
          example: '2024-12-23'
        attribution_type:
          type: string
          description: This field shows the attribution type that should be picked to show conversion stats.
          enum:
            - VIEW_THROUGH
            - CLICK_THROUGH
            - IN_SESSION
            - TOTAL_CONVERSIONS
            - CLICK_CONVERSIONS
        offset:
          type: integer
          description: |
            This field shows the position of a record in a dataset. 
            The default value for the number of campaigns to skip is 0. 
            For example, setting the offset to 50 skips the first 50 records. The resulting page number depends on your limit. With a limit of 10, an offset of 50 returns page 6.
          default: 0
        limit:
          type: integer
          description: This field shows the maximum number of campaigns displayed on a page. The default and max limit is up to 10 campaigns.
          default: 10
          maximum: 10
        metric_type:
          type: string
          description: This field shows the total or unique values of all the metrics.
          enum:
            - TOTAL
            - UNIQUE

    CampaignStatsResponse:
      type: object
      properties:
        response_id:
          type: string
          description: The response ID, which is the same as the request ID passed in the payload.
        total_campaigns:
          type: integer
          description: This field indicates the total number of campaigns that are requested in the payload.
        current_page:
          type: integer
          description: This field indicates the current page number.
        total_pages:
          type: integer
          description: This field indicates the total page. It is equal to the total campaigns, which is limited to 10 for each call and 10 to be displayed for each page.
        data:
          type: object
          description: This object contains the campaign stats. Keys are Campaign IDs.
          additionalProperties:
            type: array
            items:
              $ref: '#/components/schemas/CampaignStatsDetails'

    CampaignStatsDetails:
      type: object
      properties:
        platforms:
          $ref: '#/components/schemas/Platforms'
    
    Platforms:
      type: object
      description: 'This field indicates the platforms where the user has engaged with your communication (e.g., ANDROID, IOS, WEB, MWEB, UNKNOWN).'
      additionalProperties:
        $ref: '#/components/schemas/PlatformStats'

    PlatformStats:
      type: object
      properties:
        locales:
          $ref: '#/components/schemas/Locales'

    Locales:
      type: object
      description: This field indicates the details of the locales configured.
      additionalProperties:
        $ref: '#/components/schemas/LocaleStats'

    LocaleStats:
      type: object
      properties:
        variations:
          $ref: '#/components/schemas/Variations'

    Variations:
      type: object
      description: This object contains details of the variations of your locale.
      properties:
        all_variations:
          $ref: '#/components/schemas/VariationDetails'
        campaign_control_group:
          $ref: '#/components/schemas/VariationDetails'
        global_control_group:
          $ref: '#/components/schemas/VariationDetails'

    VariationDetails:
      type: object
      properties:
        performance_stats:
          $ref: '#/components/schemas/PerformanceStats'
        conversion_goal_stats:
          $ref: '#/components/schemas/ConversionGoalStats'
        delivery_funnel:
          $ref: '#/components/schemas/DeliveryFunnel'
        failure_breakdown:
          $ref: '#/components/schemas/FailureBreakdown'

    PerformanceStats:
      type: object
      description: This object shows your campaign's performance metrics.
      properties:
        attempted:
          type: integer
          description: Number of communication attempts made.
        sent:
          type: integer
          description: Number of communications sent.
        failed:
          type: integer
          description: Number of communications that failed to reach customers.
        bounced:
          type: integer
          description: Number of communications bounced.
        impression:
          type: integer
          description: Number of times your communication appeared to the user.
        click:
          type: integer
          description: Number of times your users clicked the message.
        opened:
          type: integer
          description: Number of communications opened by the user.
        delivered:
          type: integer
          description: Number of communications delivered to the customer.
        read:
          type: integer
          description: Number of customers who read your communications.
        closed_click:
          type: integer
          description: Number of messages closed by your customers.
        unsubscribe:
          type: integer
          description: Number of customers who have unsubscribed.
        ctr:
          type: number
          format: double
          description: 'Click-Through Rate: (Clicks / Impressions).'
        delivery_rate:
          type: number
          format: double
          description: Rate of delivery to customers.
        read_rate:
          type: number
          format: double
          description: 'UniqueRead / uniqueDelivered * 100.'
        successfully_synced:
          type: integer
        sent_rate:
          type: number
          format: double
          description: 'Sent / attempted * 100.'
        failure_rate:
          type: number
          format: double
          description: '(attempted - sent) / attempted * 100.'
        eligible_users:
          type: integer
          description: Number of eligible users.
        complaint:
          type: integer
          description: Count of complaints registered.
        hard_bounce:
          type: integer
        soft_bounce:
          type: integer
        open_rate:
          type: number
          format: double
        ctor:
          type: number
          format: double
          description: Click-through open rate.
        unsub_rate:
          type: number
          format: double
        bounce_rate:
          type: number
          format: double
        complaints_rate:
          type: number
          format: double

    ConversionGoalStats:
      type: object
      description: This object shows the conversion goal stats of your campaign.
      additionalProperties:
        $ref: '#/components/schemas/ConversionGoal'

    ConversionGoal:
      type: object
      properties:
        goal_name:
          type: string
        conversions:
          type: integer
          description: Number of conversions.
        cvr:
          type: number
          format: double
          description: Conversion rate.
        uplift:
          type: number
          format: double
          description: Percentage change in performance metrics.
        # Additional fields from large sample response
        total:
          type: integer
        unique:
          type: integer
        revenue:
          type: number
        average_order_value:
          type: number
        average_revenue_per_user:
          type: number
        gcg_uplift:
          type: number

    DeliveryFunnel:
      type: object
      description: This object shows the delivery stats of your campaign.
      properties:
        reachable_users_in_segment:
          type: integer
        segment_after_uninstall:
          type: integer
        after_fc:
          type: integer
        users_after_dup:
          type: integer
        sent:
          type: integer
        user_devices:
          type: integer
        impressions:
          type: integer
        active_device_token:
          type: integer
        after_invalid_removal:
          type: integer
        total_user_in_segment:
          type: integer
        user_with_email:
          type: integer
        user_with_email_after__h_b:
          type: integer
        user_after_duplicate_removal:
          type: integer
        after_personalization_removal:
          type: integer
        delivered:
          type: integer

    FailureBreakdown:
      type: object
      description: This object shows the failure breakdown of your campaign.
      additionalProperties:
        type: integer

    ErrorResponseSimple:
      type: object
      properties:
        title:
          type: string
        description:
          type: string
          nullable: true
        code:
          type: string

    ErrorResponseCampaignReport:
      type: object
      properties:
        error:
          type: object
          properties:
            attribute:
              type: string
            message:
              type: string
            type:
              type: string
              example: BAD REQUEST
            request_id:
              type: string