# AI Agent Access Source: https://moengage.com/docs/ai-agents Access MoEngage documentation in formats suited for AI agents, LLMs, and automation tools. Use the options below to give AI coding assistants and language models access to MoEngage documentation with less overhead than loading full HTML pages. ## Quick start * **AI coding assistants (Claude Code, Cursor, etc):** Use the [MoEngage Docs MCP server](https://www.moengage.com/docs/mcp) for the best experience. It lets your assistant search and fetch documentation from within the IDE. * **Chat interfaces (ChatGPT, Claude.ai):** Add `.md` to any docs page URL and share it in your conversation to get plain markdown instead of the full site. * **Project rules and custom instructions:** Add MoEngage's [llms.txt](https://www.moengage.com/docs/llms.txt) URL to your AI tool’s rules so it has an index of relevant MoEngage pages. * **Agent capabilities:** Use the [skill.md](https://www.moengage.com/docs/skill.md) URL or `npx skills add https://www.moengage.com/docs` so agents know what they can do with MoEngage and what inputs or constraints apply. ## MCP server The [MoEngage Docs MCP server](https://www.moengage.com/docs/mcp) gives AI agents and coding assistants direct access to MoEngage documentation and references through the Model Context Protocol. Use it to bring MoEngage knowledge into tools like Claude, Cursor, and other MCP-compatible clients. The MoEngage Docs MCP (Model Context Protocol) server connects your AI agents to MoEngage’s docs and developer resources. Configure the MoEngage Docs MCP server in your IDE or AI chat to get in-context help for your MoEngage integration. For more on the Model Context Protocol, see the [MCP documentation](https://modelcontextprotocol.io/introduction). If your AI agent supports MCP, you can add the MoEngage MCP server so it has access to MoEngage’s APIs and SDKs. The MoEngage MCP server lets you: * Get quick answers about MoEngage APIs, features, and implementation * Search documentation without leaving your editor * Find code samples and recommended patterns for typical use cases * Debug issues using docs and SDK references * Write code that integrates your app with MoEngage ## Installation To set up the MoEngage MCP server, use the contextual menu on any page and click **Connect**. Cursor Context 1 Alternatively, you can pick your IDE or AI chat provider and follow the steps below. 1. Open **Cursor** and open the `.cursor` directory in your project root. Create it if it doesn’t exist. This is where Cursor’s project configuration lives. 2. Open the `mcp.json` file in `.cursor`. Create it if it doesn’t exist. This file holds MCP server configuration for the project. 3. Add the following to `mcp.json`: ```json mcp.json theme={null} { "mcpServers": { "MoEngage Docs": { "url": "https://www.moengage.com/docs/mcp" } } } ``` 4. Save the file. 5. Restart Cursor. Claude Desktop uses `npm` to run the MoEngage MCP server. You need **Node.js** installed. See [Node.js downloads](https://nodejs.org/en/download/) for details. 1. Open **Claude Desktop**. 2. Go to **File > Settings** (Windows) or **Settings** (macOS). 3. Open the **Developer** tab. 4. Click **Edit Config**. 5. Open `claude_desktop_config.json`. This file controls MCP servers for Claude Desktop. 6. Add the following to `claude_desktop_config.json`: ```json claude_desktop_config.json theme={null} { "mcpServers": { "moengage-docs": { "command": "npx", "args": ["-y", "mcp-remote", "https://www.moengage.com/docs/mcp"] } } } ``` 7. Save the file. 8. Restart Claude Desktop. Remote MCP in Claude Desktop is currently in beta. ### Enterprise and team plans 1. Open **Claude Desktop**. 2. Go to **Admin settings > Connectors**. 3. Scroll to the bottom of the section. 4. Click **Add custom connector**. 5. Fill in: * **Name**: MoEngage MCP * **Remote MCP server URL**: `https://www.moengage.com/docs/mcp` 6. Click **Add**. ### Pro and max plans 1. Open **Claude Desktop**. 2. Go to **Settings > Connectors**. 3. Scroll to the bottom of the section. 4. Click **Add custom connector**. 5. Fill in: * **Name**: MoEngage MCP * **Remote MCP server URL**: `https://www.moengage.com/docs/mcp` 6. Click **Add**. Run the following command in your terminal: ```bash theme={null} claude mcp add --transport http MoEngage-docs https://www.moengage.com/docs/mcp ``` 1. Create a `.vscode/mcp.json` file with the following content: ```json mcp.json theme={null} { "servers": { "MoEngage Docs": { "type": "http", "url": "https://www.moengage.com/docs/mcp" } } } ``` 2. Save the file. 3. Restart VS Code. ## Usage The MoEngage MCP exposes the following tool: * **`search_mo_engage`** — Searches MoEngage’s documentation and knowledge base. Use it to find guides, API details, code examples, and implementation notes. Results include titles and links to the relevant docs. ## Per-page markdown Append `.md` to any docs page URL to get a markdown version of that page. You get content only, without HTML, nav, or scripts, which uses fewer tokens than the full page. For example, for the [API Reference introduction](/api-reference/introduction) in markdown, use: ```txt theme={null} https://www.moengage.com/docs/api-reference/introduction.md ``` ## Site-wide endpoints These endpoints follow the [llms.txt standard](https://llmstxt.org/). You can use these endpoints for markdown-formatted content. | Endpoint | Description | Size | | --------------------------------------------------------------- | ----------------------------------------------------------------------- | ------ | | [`/llms.txt`](https://www.moengage.com/docs/llms.txt) | Page index with short descriptions for the whole site | Varies | | [`/llms-full.txt`](https://www.moengage.com/docs/llms-full.txt) | Full content of all pages. Prefer section-level endpoints when possible | Large | ## skill.md The `skill.md` file describes what AI agents can do with MoEngage in a structured, machine-readable format. It makes capabilities, required inputs, and constraints explicit so agents can use your product more reliably. **URL:** [https://www.moengage.com/docs/skill.md](https://www.moengage.com/docs/skill.md) The file follows the [skill.md specification](https://agentskills.io/specification) and is kept in sync with the documentation so agents stay aligned with current MoEngage features and APIs. `llms.txt` and `skill.md` both help agents use MoEngage documentation, but they do different things. * **`llms.txt`** is a directory: it lists documentation pages with descriptions so agents know where to look. * **`skill.md`** is a capability summary: it describes what agents can accomplish with your product, what inputs they need, and what constraints apply. ### Using skill.md with agents Agents can load MoEngage’s capabilities into their context with the [skills CLI](https://www.npmjs.com/package/skills): ```bash theme={null} npx skills add https://www.moengage.com/docs ``` This adds MoEngage’s skill description to the agent so it can take actions on behalf of users (e.g. answering integration questions or suggesting API usage). Use the `skill.md` URL or the command above in your own AI setup so you get better, more accurate assistance when working with MoEngage. ### What’s in skill.md The MoEngage `skill.md` file is generated from the documentation and typically includes: * **Metadata** — Product name, description, and version. * **Capabilities** — What agents can do with MoEngage (e.g. campaigns, segments, SDK integration). * **Skills** — Concrete actions grouped by area (APIs, SDKs, data, etc.). * **Workflows** — Step-by-step procedures for common tasks. * **Integration** — Supported tools and services. * **Context** — High-level overview of MoEngage documentation and concepts. For the exact schema and fields, see the [agentskills.io specification](https://agentskills.io/specification). # Bulk Import Users and Events Source: https://moengage.com/docs/api/bulk/bulk-import-users-and-events /api/data/data.yaml post /transition/{Workspace_ID} The Bulk Import API sends multiple user and event requests in batch to MoEngage, using a single API request. You can send a batch request of a maximum of 100 KB in a single API call. All bulk API requests return a 200 response code. Debugging should be done on the user profile on the dashboard. #### User Identity Resolution In MoEngage, data ingestion uses an ID to create or update a user. For workspaces in MoEngage with [Identity Resolution](https://help.moengage.com/hc/en-us/articles/24050999467284-Unified-Identity-Identity-Resolution) enabled, you can use the Bulk Import API to create or update users using a specific identifier, such as a mobile number or email ID. These identifiers must be enabled for the workspace in the Identity Resolution dashboard. You can: * Create users through Server-to-Server Data APIs even when they do not have an ID (but have other identifiers). * Create a user or track events of a user when identifiers other than ID (for example, email ID or phone number) are known. #### Rate Limit A single bulk import API contains users, devices, and events together. Send a maximum of 10,000 users and 30,000 events per minute across all API requests. # Business Events Overview Source: https://moengage.com/docs/api/business-events/business-events-overview Create, manage, and trigger real-time business events to power automated MoEngage campaigns. The MoEngage Business Events API allows you to create and trigger specialized events that represent business occurrences—such as a flight delay, a price drop on a watched item, or the release of a new OTT series episode. These events act as triggers for **Business Event Triggered Campaigns**, allowing you to automate high-context communication based on external data points rather than just user behavior. ## Endpoints The Business Events API is a collection of the following endpoints: * [Create Business Event](/api/business-events/create-business-event): Define the schema and attributes for a new event. * [Trigger Business Event](/api/business-events/trigger-business-event): Trigger an event to initiate associated campaigns. * [Search Business Events](/api/business-events/search-business-events): Retrieve details of existing events using IDs or names. ## FAQs ### Manage Business Events The supported data types include integer, float, string, date, and array. No, business event names must be unique within your workspace. You can use the [Search Business Events API](/api/business-events/search) to fetch a list of all events associated with your workspace. ### Trigger Campaigns No, it is not mandatory to pass all defined attributes when triggering the event. Only include the attributes required for your campaign personalization. Navigate to **Engage -> Campaigns** on the MoEngage Dashboard and search for the campaign associated with your Business Event to view real-time analytics and trigger counts. The API will return a `400 Bad Request` error with the message "No active campaign found for business event name." Ensure your campaign is in the **Active** state before triggering. ## Postman Collection Test these endpoints quickly using our pre-configured Postman collection: [View MoEngage Business Events Collection](https://www.postman.com/moengage-dev/workspace/api-docs/collection/3182294-38587f83-f039-46f3-b86e-10af2c918053) # Create Business Event Source: https://moengage.com/docs/api/business-events/create-business-event /api/business-events/business-events.yaml post /business_event This API creates business events in MoEngage. You can use these events to trigger campaigns whenever they occur. In MoEngage, you can set up event-triggered campaigns to notify users about new episodes, flight delays, or price reductions on items they have viewed, wished for, or added to their carts. #### Rate Limit The rate limits are at the workspace level. You can create a maximum of 50 business events for each workspace. # Search Business Events Source: https://moengage.com/docs/api/business-events/search-business-events /api/business-events/business-events.yaml post /business_event/search This API searches for business events by specifying their event IDs. #### Rate Limit The rate limit is 100 RPM. # Trigger Business Event Source: https://moengage.com/docs/api/business-events/trigger-business-event /api/business-events/business-events.yaml post /business_event/trigger This API triggers a business event in MoEngage. You can set up campaigns to be executed when these events are triggered. #### Rate Limit For Campaigns: * You can send a maximum of 200 triggers per day * You can send a maximum of 50 triggers per hour. For Flows: * You can trigger a maximum of 3 Business Trigger flows per hour. * You can trigger a maximum of 10 Business Trigger flows per day. # Download Campaign Report Source: https://moengage.com/docs/api/campaign-reports/download-campaign-report /api/stats-report/stats-report.yaml get /campaign_reports/rest_api/{APP_ID}/{FILENAME} This API downloads campaign reports for any specific date range. You can fetch reports for one-time and periodic campaigns. #### 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() ``` # Campaigns Overview Source: https://moengage.com/docs/api/campaigns/campaigns-overview Use the MoEngage Campaigns API to create, update, test, and manage Push and Email campaigns programmatically. The MoEngage Campaigns API allows you to create and manage Push and Email campaigns. Use these endpoints to automate campaign creation, update existing campaigns, control campaign status, and retrieve campaign details. If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. ## Endpoints The Campaigns API is a collection of the following endpoints: * [Create Campaign](/api/create-campaigns/create-campaign): Creates a new Push or Email campaign. * [Update Campaign](/api/update-campaigns/update-campaign): Updates an existing Push or Email campaign in MoEngage. * [Search Campaigns](/api/get-campaign-details/search-campaigns): Fetches a list of Push, Email, or SMS campaigns with all current fields and status. * [Test Campaign](/api/test-campaigns/test-campaign): Sends a test Push or Email campaign to specific users before launching it. * [Personalized Preview](/api/test-campaigns/personalized-preview): Displays personalized content for a specific user before sending a Push, Email, or SMS campaign. * [Get Campaign Meta](/api/get-campaign-details/get-campaign-meta): Retrieves campaign details and reachability information for scheduled campaigns. * [Change Campaign Status](/api/update-campaigns/change-campaign-status): Updates the status of campaigns to stop, pause, or resume them. * [Get Child Campaigns](/api/get-campaign-details/get-child-campaigns): Retrieves child campaign execution details for Periodic or Business Event-triggered campaigns. ## FAQs ### Create Email Campaign You can use user attributes, event attributes, product sets, content API, and content block for personalizing campaigns. The syntax of the personalization Jinja is the same as supported in the MoEngage dashboard. MoEngage dedups the campaign using the request ID. If the same request ID is passed twice in 24 hours, the second campaign creation will fail. Campaigns are displayed under the same delivery type with which the campaigns are created through this API. For example, One-Time, Periodic, and so on. No, only one of the two is required for creating the campaign. If both are passed, the campaign creation will display an error. To create a campaign that uses a custom segment, include the `segmentation_details` in your campaign creation request. Within `included_filters`, set the `filter_type` to "custom\_segments" and provide the ID of your custom segment. The following code snippet shows how to incorporate a custom segment: ```json theme={null} "segmentation_details": { "included_filters": { "filter_operator": "and", "filters": [ { "filter_type": "custom_segments", "name": "segment", "id": "{{id}}" } ] } } ``` ### Create Push Campaign Yes. You can create a Push campaign for a single platform such as Android, iOS, or Web. You can also create campaigns for a combination of these platforms. Use the [Search Push Template API](/api/templates/search-push-template) and pass a request parameter such as the template name, created by, or any other supported parameter to retrieve the template ID in the response. Select a template type, such as Stylized Basic, Timer, or any other available option. Then, refer to the template's requirements and include all fields marked as mandatory for that template type. To create a campaign that uses a custom segment, include the `segmentation_details` in your campaign creation request. Within `included_filters`, set the `filter_type` to "custom\_segments" and provide the ID of your custom segment. The following code snippet shows how to incorporate a custom segment: ```json theme={null} "segmentation_details": { "included_filters": { "filter_operator": "and", "filters": [ { "filter_type": "custom_segments", "name": "segment", "id": "{{id}}" } ] } } ``` ### Update Push Campaign The template type can be modified for the required platforms, and new content needs to be provided for the updated template type. The platform can be added or removed during the update of the campaigns. You need to provide content for the new platform added to the campaign. The updated campaign starts sending out as soon as changes are done, except for Event-triggered campaigns. In Event-triggered campaigns, details are cached and take up to 30 mins to send the updated campaign. ### Update Email Campaign No, you cannot update the segmentation audience after the campaign is in Active state. You can update the segmentation audience if the campaign is in Scheduled state or create a duplicate by stopping the existing campaign to pass new segmentation details. The updated campaign starts sending out as soon as changes are done except for Event-triggered campaigns. In Event-triggered campaigns, details are cached and take up to 30 mins to send the updated campaign. You must call the "GET" API by the campaign name, channel, or any other filters to fetch the campaign ID of the desired campaign. For more information, refer to [Search Campaigns](/api/campaigns/campaigns#search_campaigns). ### Search Campaigns - Push Yes. To fetch flow node campaigns, you must pass the `include_child_campaigns` key value as `true`. Use the `flow_name` and `flow_id` keys in the response. These keys indicate that the campaign is part of a flow. The response will include all flow node campaigns, regardless of the flow delivery type, and Engage campaigns with a delivery type of `one_time`. ### Search Campaigns - SMS Yes. To fetch flow node campaigns, you must pass the `include_child_campaigns` key value as `true`. Use the `flow_name` and `flow_id` keys in the response. These keys indicate that the campaign is part of a flow. No, we currently do not have any filter in the request body for the sender name. Yes. To fetch archived campaigns, you must pass the `include_archived_campaigns` key value as `true`. ### Test Push Campaign Yes, you can send the test campaign to any user by passing identifier as "Email". The campaign sent will not be personalized. The values passed under personalization details will be used for all users to whom the test campaign is to be sent and the remaining user attributes values will be picked up from the user profile. ### Test Email Campaign Yes, you can send the test campaign to any user by passing identifier as "Email". The campaign sent will not be personalized. The values passed under personalization details will be used for all users to whom the test campaign is to be sent and the remaining user attributes values will be picked up from the user profile. ### Get Campaign Meta No, reachability is an estimated value that may vary over time due to factors such as app installations, uninstalls, or changes in email subscription status. No, reachability is calculated once daily and cached for 24 hours. Multiple API calls within the same day will return the cached value. ### Personalized Preview Yes, you can use custom templates with the Personalization Preview. The API will personalize the content within the template based on the user identifier provided and return the personalized HTML as a response. Yes, you can pass event details as input to the API. Ensure the event name matches the one in your workspace. ### Change Campaign Status Periodic campaign only supports Pause and Resume actions of the campaign. You can stop only One-time campaigns. No, after the One-time campaign moved to the Active state, you cannot stop it. ## Postman Collections We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/workspace/api-docs/folder/3182294-c560e43e-4e5e-4d1c-a100-f5f5070780b1?action=share\&creator=3182294\&ctx=documentation) to view the Postman collection. # Cards Overview Source: https://moengage.com/docs/api/cards/cards-overview Use the MoEngage Cards API to fetch, filter, and delete user-specific cards from your application. The MoEngage Cards API allows you to fetch and delete user-specific cards from the MoEngage database. Use these endpoints to retrieve cards for a user, filter them by platform and category, check for updates since the last sync, and remove specific card campaigns. If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. ## Endpoints The Cards API is a collection of the following endpoints: * [Fetch Cards](/api/cards/fetch-cards-for-user): Retrieves all active and updated cards for a specific user, supporting filtering and pagination. * [Delete Cards](/api/cards/delete-cards-for-user): Deletes specific card campaigns for a user from the MoEngage Cards database. ## FAQs ### Fetch Cards You can use the `prev_sync_card_ids` (list of card IDs from the previous sync) and `last_updated_time` (Unix epoch timestamp of the last sync) fields in the request body. The API will return only the new or updated cards. Yes. You can filter by platform using the `platforms` array (e.g., `["ANDROID", "WEB"]`) and by category using the `card_category` string field in the request body. You must provide either the `uid` (MoEngage Standard ID like Email or Mobile Number) or the `unique_id` (Platform-specific device identifier). One of these is required. The *unique\_id* is the unique value that identifies the user to whom the cards need to be shown. It is a platform-specific device identifier that can be generated. The *uid* is the unique MoEngage Standard ID (Email ID Standard or the Mobile Number Standard) that identifies the user. ### Delete Cards The Delete Cards API requires complex filtering parameters (campaign IDs, specific platforms, and user identifiers) which are best transmitted via a JSON body, even though this deviates from the standard REST pattern for `DELETE` requests. Yes, you can specify the `platforms` array in the request body (e.g., `["android"]`) to delete the cards only from those specific platforms. If omitted, it deletes from all associated platforms. The *unique\_id* is the unique value that identifies the user to whom the cards need to be deleted. It is a platform-specific device identifier that can be generated. The *uid* is the unique MoEngage Standard ID that identifies the user. ## Postman Collections We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/dpuqrlz/moengage-cards) to view the Postman collection. # Delete Cards for User Source: https://moengage.com/docs/api/cards/delete-cards-for-user /api/cards/cards.yaml delete /cards/delete This API deletes cards for a specified user from the MoEngage Cards database. #### Rate Limit The rate limit is **50K RPM** (Requests Per Minute) and is applicable at the workspace (App) level. # Fetch Cards for User Source: https://moengage.com/docs/api/cards/fetch-cards-for-user /api/cards/cards.yaml post /cards/fetch This API retrieves all active and updated cards for a specific user from the MoEngage Cards database. You can filter the search results based on the platform and card category and check if any card was updated for the user since the previous sync. #### Rate Limit The rate limit is **50K RPM** (Requests Per Minute) and is applicable at the workspace (App) level. # Add Catalog Attributes Source: https://moengage.com/docs/api/catalog/add-catalog-attributes /api/catalog/catalog.yaml patch /catalog/{catalog_id}/attributes This API adds new attributes to the catalog. If the API request contains attributes that already exist, they will not be added again. #### Rate Limit * Request limit: You can add 100 attributes per minute OR 1000 attributes per hour. * Payload size limit - 5 MB only when Content-Length header is provided. # Catalog Overview Source: https://moengage.com/docs/api/catalog/catalog-overview Manage product and item catalogs, define attributes, and handle bulk item ingestion. The MoEngage Catalog API allows you to manage product and item catalogs. Use these endpoints to create new catalogs, define custom schemas, and perform bulk operations for ingesting, updating, or deleting items. ## Endpoints The Catalog API is a collection of the following endpoints: * [Create Catalog](/api/catalog/create-catalog): Creates a new catalog with a unique name. * [Add Catalog Attributes](/api/catalog/add-catalog-attributes): Adds new attributes to the catalog. * [Add Items](/api/items/add-items): Ingests items into an existing catalog. * [Get Items](/api/items/get-items): Retrieve item attribute details. * [Update Items](/api/items/update-items): Updates items with new attribute values. * [Delete Items](/api/items/delete-items): Deletes existing items in a given catalog. ## FAQs ### Catalog Management The API will return a `409 Conflict` error with the error code `duplicate-catalog-name`. Catalog names must be unique within your workspace. Yes, you can use the **Add Catalog Attributes** (PATCH) endpoint. Note that if you send attributes that already exist in the schema, they will be ignored and listed in the `duplicate-item-attributes` array in the response. You can define up to 50 attributes per catalog, including the 4 mandatory attributes. API catalogs automate real-time updates such as price and quantity. They offer improved efficiency and scalability by updating only specific products, unlike file-based catalogs, which require the replacement of the whole file at each processing schedule. These APIs can be accessed and used to update from any location. Each error code is a uniquely defined shorthand representation for the type of error, providing a quick reference that can be used to diagnose, troubleshoot, and address the problem based on a predefined set of error conditions. No, the datatype cannot be changed once an attribute has been defined in the catalog. You can add a new attribute to the catalog with a different datatype as needed. A maximum of 50 attributes can be added to the catalog. Before updating existing items with new attributes, you must first add the new attribute to the catalog schema using the 'Add catalog attribute' API. Only then will your update requests for including new attributes be successful. The request will be processed successfully marking such items as invalid. The response will include the count of these invalid item IDs. ### Item Ingestion and Updates The API returns a `200 OK` with a detailed breakdown. The response body will include a `valid` count and an `invalid` count with a `details` array specifying which `document_ids` failed and why (e.g., data type mismatch or missing attributes). No. The `id` is the primary key. To change an ID, you must delete the existing item and ingest it as a new item. Yes, the bulk-delete endpoint supports a maximum of 50 item IDs per request. All MoEngage catalog APIs operate synchronously. This means that every catalog API request is processed in real time, and you can see the changes instantly. ### Get Item Details Each error code is a uniquely defined shorthand representation for the type of error, providing a quick reference that can be used to diagnose, troubleshoot, and address the problem based on a predefined set of error conditions. No, the data type cannot be changed once an attribute has been defined in the catalog. You can add a new attribute to the catalog using the [Add new catalog attribute API](/api/catalog/add-catalog-attributes) with a different data type as needed. ## Postman Collections Test these endpoints immediately using our Postman collection. [View Postman Collection](https://www.postman.com/moengage-dev/api-docs/collection/seck3f6/moengage-catalog-api) # Create Catalog Source: https://moengage.com/docs/api/catalog/create-catalog /api/catalog/catalog.yaml post /catalog This API creates a new catalog with a unique name. You can specify the necessary attributes along with their respective data types. #### Rate Limit * Request limit: You can create 100 catalogs per minute OR 1000 catalogs per hour. * Payload size limit: 5 MB only when Content-Length header is provided. # Sync Cohort Members Source: https://moengage.com/docs/api/cohort-sync/sync-cohort-members /api/cohort-audience/cohort-audience.yaml post /v1/integrations/cohortsync This API adds or removes a list of users from a custom segment (cohort) in MoEngage. * The Cohort Sync API only matches users already present in MoEngage based on the User ID (`uid`) provided in the request. This API does not create new users. * This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. #### Rate Limits Please adhere to the following limits: * **Frequency:** 300 requests per minute. * **Payload Structure:** One payload per request (each payload can contain multiple UIDs). * **Size Limit:** The payload size cannot exceed **128KB**. #### User Resolution The Cohort Sync API resolves existing users in MoEngage based on predefined user identifiers: * **Identifier:** We primarily rely on the **User ID** (`uid`) provided in the request payload. * **Matching:** This must match the Unique User ID set in MoEngage (typically available for registered or logged-in users). * **Profile Association:** Each Unique User ID corresponds to a single user profile. Even if a user is logged in across multiple devices, the devices are associated with that single user profile. # Content Blocks Overview Source: https://moengage.com/docs/api/content-blocks/content-blocks-overview Fetch, create, and manage reusable content blocks. Content blocks allow marketers to reuse the same content across multiple campaigns. Instead of recreating standard elements for every message, you can create a block once—such as a header, footer, or a designed call-to-action button—and reference it everywhere. This MoEngage Content Block API allows you to fetch, create, and update these content blocks on your MoEngage dashboard. ## Endpoints The Content Block API is a collection of the following endpoints: * [Create Content Block](/api/content-blocks/create-content-block): Creates a content block. * [Update Content Block](/api/content-blocks/update-content-block): Updates a content block specified by its ID. * [Get Specific Content Blocks](/api/content-blocks/get-specific-content-blocks): Fetches specific content blocks from the available content blocks. * [Search Content Blocks](/api/content-blocks/search-content-blocks): Searches the content blocks created in your MoEngage account. ## Postman Collections We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/3486165-5dc87a9b-a3ef-442f-9d45-512253c6b891) to view our official Postman collections. # Create Content Block Source: https://moengage.com/docs/api/content-blocks/create-content-block /api/content-blocks/content-blocks.yaml post /content-blocks This API creates a content block in MoEngage. # Get Specific Content Blocks Source: https://moengage.com/docs/api/content-blocks/get-specific-content-blocks /api/content-blocks/content-blocks.yaml post /content-blocks/get-by-ids This API retrieves specific content blocks from the available content blocks in your MoEngage account. # Search Content Blocks Source: https://moengage.com/docs/api/content-blocks/search-content-blocks /api/content-blocks/content-blocks.yaml post /content-blocks/search This API searches for the available content blocks in your MoEngage account. # Update Content Block Source: https://moengage.com/docs/api/content-blocks/update-content-block /api/content-blocks/content-blocks.yaml put /content-blocks This API updates the content blocks in MoEngage. # Delete a Coupon File from the Coupon List Source: https://moengage.com/docs/api/coupon-files/delete-a-coupon-file-from-the-coupon-list /api/coupons/coupons.yaml delete /coupon-list/{coupon_list_id}/files/{coupon_file_id} This API removes a specific coupon file from a coupon list. It is useful in scenarios where a test file or incorrect file is inadvertently uploaded, thereby ensuring the accuracy and effectiveness of your coupon list management. **Information** There is no request body or content to send for this request except for headers. #### Rate Limit You can delete: * 5 coupon files per minute or * 50 coupon files per day # Fetch a Coupon File from Coupon List Source: https://moengage.com/docs/api/coupon-files/fetch-a-coupon-file-from-coupon-list /api/coupons/coupons.yaml get /coupon-list/{coupon_list_id}/files/{coupon_file_id} This API retrieves the details of a particular coupon file added to a given coupon list. This includes information such as file status, the number of added coupons, and the file addition date. **Information** There is no request body or content to send for this request except for headers. #### Rate Limit You can fetch 10,000 coupon files from a coupon list per day. # Fetch All Coupon Files From Coupon List Source: https://moengage.com/docs/api/coupon-files/fetch-all-coupon-files-from-coupon-list /api/coupons/coupons.yaml get /coupon-list/{coupon_list_id}/files This API retrieves the details of each file in the given coupon list that is added and not deleted. The information retrieved will include the file's status, the number of coupons added from each file, and the respective file's addition date, thereby providing a comprehensive breakdown of each file's information for improved management and tracking. There is no request body or content to send for this request except for headers. #### Rate Limit You can fetch 10,000 coupon files from coupon lists per day. # Upload a Coupon File to the Coupon List Source: https://moengage.com/docs/api/coupon-files/upload-a-coupon-file-to-the-coupon-list /api/coupons/coupons.yaml post /coupon-list/{coupon_list_id}/files After you create a coupon list, you must add coupons to the list to be distributed through campaigns. If a coupon list has been running for some time, it may be running low after serving several campaigns. Using this API, you can replenish an older list or populate a new list by providing the URL of a file containing the coupons, thereby enabling their distribution through various campaigns. These coupons can be provided through a file, and the API requires the URL where your coupon file is hosted. **Information** Upon API request, file processing begins, and the file status will be **PENDING** by default. * For convenience, you can set up a callback URL to trigger when the file's processing is completed. * You can check the processing status using the [Fetch a Coupon File API](https://www.moengage.com/docs/api/coupon-files/fetch-a-coupon-file-from-coupon-list) to get the status separately. #### Rate Limit You can upload: * 5 coupon files to a coupon list per minute or * 50 coupon files to a coupon list per day **Note:** * **Payload size limit**: 64 MB for manual uploads or 100 MB for URL uploads. * **Additional limits**: The maximum number of coupons per coupon list is 100 million. # Activate Coupon List Source: https://moengage.com/docs/api/coupon-lists/activate-coupon-list /api/coupons/coupons.yaml put /coupon-list/{coupon_list_id}/activate This API reactivates archived coupon lists, provided the expiry date is in the future. **Information** * Only active coupon lists can be utilized in campaigns. * If you need to modify the expiry date and activate a coupon list, you must use the [Update a Coupon List API](#operation/updateCouponList). #### Rate Limit You can activate 100 coupon lists per day. # Archive a Coupon List Source: https://moengage.com/docs/api/coupon-lists/archive-a-coupon-list /api/coupons/coupons.yaml put /coupon-list/{coupon_list_id}/archive This API transitions an active coupon list to an archived status. Upon archival, the coupon codes within the list are deleted. Consequently, any campaigns that were previously dependent on this list will no longer be able to utilize the dynamic coupon allocation. **Information** Verify the usage of a given coupon list in active or planned campaigns before archiving it. #### Rate Limit You can archive 100 coupon lists per day. # Create a Coupon List Source: https://moengage.com/docs/api/coupon-lists/create-a-coupon-list /api/coupons/coupons.yaml post /coupon-list This API creates single-use coupon codes. You can use this API to create and organize distinct lists for different coupon code categories. **Information** This API creates the coupon list with basic specifications only. The coupons should be added using [Upload the Coupons](https://www.moengage.com/docs/api/coupon-files/upload-a-coupon-file-to-the-coupon-list) API to this coupon list before utilizing it in campaigns. #### Rate Limit You can create 100 coupon lists per day. # Fetch All Coupon Lists Source: https://moengage.com/docs/api/coupon-lists/fetch-all-coupon-lists /api/coupons/coupons.yaml get /coupon-list This API fetches all created coupon lists in a specific workspace. By default, this API returns the coupon lists marked with an *ACTIVE* status. In return, it offers detailed specifications of the active coupon lists, respective configurations, statuses, expiry dates, and alert conditions, including on-time data on the total coupons added and those that are currently available. **Information** There is no request body or content to send for this request except for the headers and parameters. #### Rate Limit You can fetch 10,000 coupon lists per day. # Fetch Coupon List Details Source: https://moengage.com/docs/api/coupon-lists/fetch-coupon-list-details /api/coupons/coupons.yaml get /coupon-list/{coupon_list_id} This API retrieves the specifications of a particular coupon list. It includes information such as configurations, statuses, expiry dates, and alert conditions with real-time counts of added and currently available coupons. Using this API, you can easily access and manage critical data about individual coupon lists. **Information** There is no request body or content to send for this request except for headers and parameters. #### Rate Limit You can fetch 10000 coupon lists per day. # Update a Coupon List Source: https://moengage.com/docs/api/coupon-lists/update-a-coupon-list /api/coupons/coupons.yaml patch /coupon-list/{coupon_list_id} This API modifies existing coupon lists within a defined workspace. It facilitates changes to specifications like list name, expiry date, and alert settings, thereby promoting efficient coupon operations management. **Information** This API reactivates the *ARCHIVED* or *EXPIRED* coupon list upon modification, provided the list has a future expiration date. #### Rate Limit You can update 100 coupon lists per day. # Coupon Management Overview Source: https://moengage.com/docs/api/coupons/coupons-overview Manage unique coupon lists, upload coupon codes, and generate usage reports within the MoEngage system. The MoEngage Coupon Management API allows you to organize and distribute unique, single-use coupon codes at scale. Use these endpoints to automate the lifecycle of coupon lists—from creation and file uploads to activation, archival, and detailed usage reporting. ## Endpoints The Coupon Management API is categorized into three functional areas: ### Coupon Lists (Metadata and Status) * [Create a Coupon List](/api/coupon-lists/create-a-coupon-list): Defines a new category for unique codes. * [Fetch All Coupon Lists](/api/coupon-lists/fetch-all-coupon-lists): Retrieves a list of active or archived coupon containers. * [Fetch Coupon List Details](/api/coupon-lists/fetch-coupon-list-details): Retrieves real-time counts of available vs. total coupons. * [Update a Coupon List](/api/coupon-lists/update-a-coupon-list): Modifies names, expiry dates, or alert settings. * [Activate Coupon List](/api/coupon-lists/activate-coupon-list): Reactivates archived lists with a new expiry date. * [Archive a Coupon List](/api/coupon-lists/archive-a-coupon-list): Transitions a list to inactive and deletes associated codes. ### Coupon Files (Inventory Management) * [Upload Coupon File](/api/coupon-files/upload-a-coupon-file-to-the-coupon-list): Populates a list via a hosted file URL. * [Fetch All Coupon Files](/api/coupon-files/fetch-all-coupon-files-from-coupon-list): Tracks the status of all uploaded batches. * [Fetch a Coupon File](/api/coupon-files/fetch-a-coupon-file-from-coupon-list): Checks the processing status (e.g., PENDING) of a specific file. * [Delete a Coupon File](/api/coupon-files/delete-a-coupon-file-from-the-coupon-list): Removes specific batches (useful for correcting upload errors). ### Reports * [Generate Usage Report](/api/reports/generate-usage-report): Generates a detailed usage report for a specific coupon list, providing details on which user received which coupon. ## Postman Collections We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/y1e45ee/moengage-coupon-management) to view our official Postman collections. # Create Campaign Source: https://moengage.com/docs/api/create-campaigns/create-campaign /api/campaigns/campaigns.yaml post /campaigns This API creates a new Push or Email campaign in MoEngage with specified content, audience, and delivery settings. **API Enablement** If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. #### Rate Limits You can create 5 campaigns per minute, 25 campaigns per hour, and 100 campaigns per day. # Segments Overview Source: https://moengage.com/docs/api/custom-segments/custom-segments-overview Create, update, and manage your file-based, filter-based, and cohort-synced segments. The MoEngage Segments API allows you to manage your audience segments. This suite includes the **v2 API** for handling high-volume file-based segments and segment lifecycles, the **v3 API** for dynamic, filter-based segments, and the **Cohort Sync API** for synchronizing external audiences directly with MoEngage. ## Endpoints The Segments API is a collection of the following endpoints: ### File Segments (v2) The File Segments API allows you to create and manage segments by importing users from CSV files hosted at a URL. * [Create File Segment](/api/file-segments/create-file-segment): Creates a new file segment from a CSV file URL. * [Add Users to File Segment](/api/file-segments/add-users-to-file-segment): Adds a list of users from a CSV file to an existing file segment. * [Remove Users from File Segment](/api/file-segments/remove-users-from-file-segment): Removes a list of users from a CSV file from an existing file segment. * [Replace Users in File Segment](/api/file-segments/replace-users-from-file-segment): Replaces all users in an existing file segment with a new list of users from a CSV file. ### Manage Segments (v2) The Manage Segments API allows you to control the lifecycle of your segments by archiving or unarchiving them. * [Archive Segment](/api/manage-segments/archive-segment): Archives an existing segment (File or Filter). * [Unarchive Segment](/api/manage-segments/unarchive-segment): Unarchives an existing segment, making it active again. ### Filter Segments (v3) The Filter Segments API allows you to create and manage dynamic segments based on user attributes and behavioral filter conditions. * [List Segments](/api/filter-segments/list-segments): Lists all filter segments. * [Create Filter Segment](/api/filter-segments/create-filter-segment): Creates a new filter segment based on a set of filter conditions. * [Get Segment by ID](/api/filter-segments/get-segment-by-id): Fetches a specific segment (File or Filter) by its ID. * [Update Filter Segment](/api/filter-segments/update-filter-segment): Updates an existing filter segment by its ID. ### Cohort Sync The Cohort Sync API allows you to synchronize cohorts or audiences created in your own ecosystem directly with MoEngage. This server-to-server integration enables you to add or remove users from custom segments dynamically, ensuring your marketing campaigns always target the most relevant audience. * **Automated Segment Creation:** Automatically creates a custom segment in MoEngage if it doesn't already exist. * **Dynamic Membership:** Real-time updates to segments allow scheduled campaigns to engage the latest set of users. * **No Middleware Needed:** Direct server-to-server calls remove the need for manual CSV uploads or hosting external URLs. * **Increased Efficiency:** Ideal for segment operations involving smaller subsets of users. **Endpoint:** * [Sync Cohort Members](/api/cohort-sync/sync-cohort-members): Adds or removes users from a custom segment. These API endpoints do not currently support Team-level scoping. All segments generated using these calls will be assigned to the Default Team automatically. ## FAQs ### Filter-Based Segments You can generate the payload directly from the MoEngage Dashboard. Navigate to **Test & Debug** -> **Segment Payload**, choose your filters, and click **Generate Payload**. Use the **List Segment API** with the `name` query parameter to filter and retrieve the unique ID of the desired segment. Both the name and the definition (filters) of a segment must be unique. If the definition matches an existing segment, the API returns a 409 Conflict. In the case of a 409 error, the response payload includes the `existing_cs_name` and `existing_cs_id` of the conflicting segment. Please connect with your account manager. ### File-Based Segments Segment processing is asynchronous. MoEngage first creates the segment container (showing zero users) and then processes the file. The count will update once processing is complete. No. File segments can only be updated (add/remove/replace) via the File Segment API using CSV imports. For attribute-based updates, use Filter Segments. ### Manage Segments Archiving allows you to reuse segments for A/B testing or historical analysis without recreating them from scratch, while keeping your active segment list within the 1000-segment limit. ### Cohort Sync The Cohort Sync API enables the creation of segments without needing separate files or CSVs, eliminating the requirement for a separate path or URL as seen in the File Segment API. Segment creation can be initiated by making a direct server-to-server call, eliminating the additional steps required for generating user files. The Cohort Sync API is ideal for segments or segment operations involving fewer users. The Cohort Sync API does not create new users in MoEngage. Instead, it resolves existing users in MoEngage based on predefined user identifiers and assigns them to the corresponding custom segment created through Cohort Sync. ## Postman Collections Test these endpoints quickly by importing our Postman collections: [File Segments](https://www.postman.com/moengage-dev/api-docs/collection/z8f27qa/moengage-custom-segment-api), [Filter Segments](https://www.postman.com/moengage-dev/api-docs/collection/s16aovr/moengage-custom-segment-filter-based-crud-api-s), and [Cohort Sync](https://www.postman.com/moengage-dev/api-docs/collection/2siizsq/moengage-cohort-audience-sync-revamp?action=share\&creator=3182294) in Postman. # Data Overview Source: https://moengage.com/docs/api/data/data-overview Manage users, track events, handle devices, and perform bulk data operations. The MoEngage Data API provides a comprehensive suite of endpoints designed to help you manage data within MoEngage. This API enables you to create and update user profiles, track user actions (events), manage device information, and handle large-scale data ingestion via bulk and file import operations. ## Endpoints The Data API is a collection of the following API endpoints: * [Track User](/api/user/track-user): Adds or updates users and user properties in MoEngage. * [Get User](/api/user/get-user): Facilitates the retrieval of information of users. * [Merge User](/api/user/merge-users): Merges two users in MoEngage based on their ID. * [Delete User](/api/user/delete-users): Deletes users in MoEngage. * [Track Event](/api/event/track-event): Tracks the actions of a user. * [Track Device](/api/device/track-device): Adds or updates devices and device properties in MoEngage. * [Device Opt-out](/api/device/device-opt-out): Blocks or unblocks specific devices from receiving push notifications. * [Trigger File Imports](/api/file-import/trigger-file-imports): Triggers scheduled file imports. * [Import Details](/api/file-import/import-details): Fetches the status at an import level. * [Import File Run History](/api/file-import/import-file-run-history): Fetches the file processing status of each file contained in an import. * [Bulk Import](/api/bulk/bulk-import-users-and-events): Sends multiple user and event requests in batch to MoEngage. * [Install Tracking](/api/tracking/track-app-install): Tracks the install attribution data in MoEngage. * [Test connection](/api/utilities/test-connection-api): Validates if the entered endpoint details are valid. For workspaces in MoEngage with the *User Identity Resolution* feature enabled, use the following Data APIs to create or update users using a specific identifier, such as a mobile number or email ID, as configured in **Settings** > **Data** > **Identity Resolution**: * Track User * Create Event * Bulk Import For more information, refer to [User Identity Resolution](https://help.moengage.com/hc/en-us/articles/24050999467284-Unified-Identity-Identity-Resolution). You can: * Create users through Server-to-Server Data APIs even when they do not have an ID (but have other identifiers). * Create a user or track events of a user when identifiers other than ID (for example, email ID or phone number) are known. ## Request Body The request body contains the mandatory field called `customer_id`. It is the unique identifier set and passed on from the MoEngage SDK as `USER_ATTRIBUTE_UNIQUE_ID` and is visible on the dashboard as `ID`. `customer_id` is used to: * Identify or create a user in MoEngage. * Associate the events with the corresponding unique user profiles in MoEngage. On receiving a Data API request in MoEngage, the `customer_id` is used to verify if the user exists in MoEngage. If the user does not exist, a new user is created with the attributes or events. * The maximum limit for the request body is 128 KB. * Any string of more than one characters is allowed for `customer_id` except the following values - \['unknown', 'guest', 'null', '0', '1', 'true', 'false', 'user\_attribute\_unique\_id', '(empty)', 'na', 'n/a', '', 'dummy\_seller\_code', 'user\_id', 'id', 'customer\_id', 'uid', 'userid', 'none', '-2', '-1', '2'] For example, a user created using the following request is visible in the dashboard user profile as displayed. ### Sample Request Body Below is a sample request body for the Create User API: ```json theme={null} { "type": "customer", "customer_id": "USERID1234", "attributes": { "first_name":"John", "name":"John Smith", "plan_expiry_date":"2020-05-31T00:00:00Z", "super_user":true, "user_persona":"browsers", "platforms" : [{"platform":"ANDROID", "active":"true"}] } } ``` You can not use "moe\_" as a prefix while naming events, event attributes, or user attributes. It is a system prefix and using it might result in periodic blacklisting without prior communication. ### Supported Datetime Formats You can pass the datetime in the following formats in the request body: | Datetime Format | Example | | :------------------------------------------- | :------------------- | | `“datetime_format”:YYYY-MM-DD[T]HH:mm:ss[Z]` | 2019-03-12T17:36:05Z | | `“datetime_format”: "YYYY-MM-DD"` | 2022-01-22 | MoEngage performs the following validation on datetime formats before ingesting data into its system: * Future and past date values are accepted and ingested. * Any date values with incorrect calendar values (e.g., 2019-15-12 where 15 is not a valid month) are ingested as strings. * Any datetime values incompatible with the formats mentioned above are converted to strings and then ingested. ## Response Response to the Data API is a JSON object. On a successful data API request, you will receive the following response: ```json theme={null} { "status": "success", "message": "Your request has been accepted and will be processed soon.", "request_id": "kXwpDESb" } ``` On a failed data API request, you will receive the following response: ```json theme={null} { "status": "fail", "error": { "type": "TypeError", "message": "expected string", "request_id": "kXwpDESb" } } ``` ### Response Codes The following status codes and associated error messages are returned when the request results in an error. | Error Code | Type | Message | Description | | :--------- | :---------------------------- | :--------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 | Missing header value | The Content-Type Header is required | The header value for content type is missing | | 400 | Empty request body | A valid JSON document is required | The request body is empty | | 400 | Malformed JSON | Could not decode the request body. The JSON was incorrect or not encoded as UTF-8. | The request JSON is not formed correctly | | 400 | Blacklisted | Your account is blacklisted, Please contact MoEngage. | Your App is blacklisted in MoEngage | | 400 | InvalidParams | Given app\_id is invalid. | The App ID is invalid. | | 400 | ParamsRequired | app\_id is required in path/query params. | App ID is missing in the path or query params. | | 400 | Empty request body | A valid JSON document is required | The request body is empty. | | 400 | Body type is not JSON | A valid JSON document is required. | String Payload. | | 400 | MissingAttributeError | key is expected to be datatype | The specified attributes are invalid | | 401 | Authentication Required | Authentication Header Required | Authentication header is missing from the request. | | 401 | Authentication required | No identity information found | Authentication header is empty. | | 401 | Authentication required | Invalid identity information found | Failure to decode app\_key and app\_secret. | | 401 | Authentication required | APP\_KEY missing in the authentication header | App\_key is not present in the authentication header. | | 401 | Authentication required | APP\_SECRET missing in the authentication header | App\_secret is not present in the authentication header. | | 401 | Authentication required | App Secret key mismatch. Please login to the dashboard to verify key | App secret key is wrong. | | 401 | Authentication required | Invalid APP\_ID used in Authentication Header | You have used an invalid APP ID in the authentication header. | | 403 | Account Suspended | Account Suspended | Your account is suspended. | | 403 | Account Temporarily Suspended | Account Temporarily Suspended | Your account is suspended temporarily. | | 409 | Authentication Mismatch | App key mismatch in params and authentication | App\_key in parameters and authentication does not match. | | 409 | Authentication required | App Secret key is not set. Please login to the dashboard to set a key | App Secret not set. | | 413 | Payload too large | The payload can not exceed 128KB | Request payload size is too large. | | 415 | Unsupported Media Type | Unsupported Media Type | Unsupported media type. | | 429 | Rate Limit Exceeded | Rate Limits for User / Event exceeded | You have exceeded the rate limits (number of users or events per minute) defined for your MoEngage account. | | 5xx | Server Error | Any other exception | This response is returned when the system runs into an unexpected error. We recommend that you retry every 2 seconds for a maximum of 5 times in such cases. | ## User Attributes | Key name | Display name | Fetch through Get User API | Update through Track User API | Create through Track User API | | :-------------------------- | :------------------------------------- | :------------------------- | :---------------------------- | :---------------------------- | | publisher\_name | Publisher Name | yes | no | yes | | campaign\_name | Campaign Name | yes | no | yes | | t\_rev | LTV | yes | no | no | | t\_trans | No of Conversions | yes | no | no | | moe\_ip\_city | Last Known City | yes | no | no | | moe\_ip\_pin | Last Known Pincode | yes | no | no | | moe\_ip\_subdivision | Last Known State | yes | no | no | | moe\_ip\_country | Last Known Country | yes | no | no | | moe\_dtzo | User Timezone Offset (Mins) | yes | no | no | | u\_s\_c | No. of Sessions | yes | no | no | | u\_l\_a | Last Seen | yes | no | yes | | cr\_t | First Seen | yes | no | yes | | u\_mb | Mobile Number (Standard) | yes | yes | yes | | uid | ID | yes | yes | yes | | u\_bd | Birthday | yes | yes | yes | | u\_em | Email (Standard) | yes | yes | yes | | locale\_language\_display | Local Language | yes | no | no | | locale\_country\_display | Local Country | yes | no | no | | uninstall\_time | Uninstall time | yes | no | no | | installed | Install Status | yes | no | no | | moe\_cr\_from | User Creation Source | yes | no | no | | u\_n | Name | yes | yes | yes | | u\_ln | Last Name | yes | yes | yes | | u\_gd | Gender | yes | yes | yes | | u\_fn | First Name | yes | yes | yes | | geo | Geolocation | yes | no | no | | moe\_wa\_subscription | WhatsApp Subscription Status | yes | yes | yes | | moe\_em\_unsub\_categories | Email Unsubscribed Categories | yes | yes | yes | | moe\_gaid | Google Advertising ID (Android) | yes | no | yes | | advertising\_identifier | Advertising Identifier (iOS \&Windows) | yes | no | yes | | web subscription url | Web Push Subscription Page URL | - | - | - | | moe\_sub\_w | Web Push Subscription Status | yes | yes | yes | | moe\_w\_ds | Browser Details | yes | no | no | | moe\_mweb | Mobile User | yes | no | yes | | moe\_i\_ov | OS Version iOS | - | - | - | | moe\_it | Creation Source | no | no | no | | moe\_spam | Spam | yes | yes | yes | | moe\_unsubscribe | Unsubscribe | yes | yes | yes | | moe\_hard\_bounce | Hard Bounce | yes | yes | yes | | moe\_rsp\_android | Reachability Push Android | yes | no | no | | moe\_rsp\_ios | Reachability Push iOS | yes | no | no | | moe\_rsp\_web | Reachability Push Web | yes | no | no | | moe\_rsu | Reachability Push | yes | no | no | | moe\_sms\_subscription | SMS Subscription Status | yes | yes | yes | | moe\_ds\_bts\_push\_hour | Best time to send Push | yes | no | no | | moe\_ds\_bts\_email\_hour | Best time to Email | yes | no | no | | moe\_ds\_bts\_sms\_hour | Best time to send SMS | yes | no | no | | moe\_ds\_mpc\_best\_channel | Most Preferred Channel | yes | no | no | ## Dashboard User Profile On sending data through the data API, it will be populated in the user profile as shown below: Newuserprofile ## Limits The Data API is designed to handle high volumes of data across our customer base. We enforce API limits to ensure responsible use of the API. Refer to the respective endpoint documentation for rate limits. * If your requirement exceeds the default limits, you can contact the MoEngage support team to increase the limits. * Make sure to adhere to the Fair Usage Policy (FUP) for high-frequency user data ingestion. This is mandatory to prevent disruption to data processing in your workspace. For more information, refer to the [Fair Usage Policy (FUP)](https://help.moengage.com/hc/en-us/articles/24151864954644-Fair-Usage-Policy-FUP). ## FAQs ### Track User Please attempt exponential backoff of requests to ensure there is no data loss due to 5xx errors. Getting a 200 status code as a response from MoEngage only indicates that the users in your API payload have been accepted for processing. It does not ensure that the users sent to MoEngage have been successfully ingested. \ Although, this happens very rarely and you can search for newly ingested users in:\ **Segment > Create Segment > Search for users using their IDs** Please use the [Get User API](/api/user/get-user) to export the users. Please use the [Delete User API](/api/user/delete-users-in-bulk) to delete existing users in MoEngage. ### Get User All available users will be found in the `users` key, and users not available will be found in the `users_not_found` key. Please refer to the sample response in this doc. If the `user_fields_to_export` is not passed, then all custom attributes and exportable standard attributes will be returned. For specific fields, `user_fields_to_export` needs to be passed along with the list of required fields. ### Merge User No, the merged user will get deleted after calling this API. All the user attributes and devices of the merged user will be transferred to the retained user. The reachability status of the user will be recalculated based on the devices present after merging the user. Any registered user present in the MoEngage system can be merged with another registered user irrespective of the source of creation. Not necessarily; we allow the merging of users with or without devices. No. No. This user will get deleted, and if any devices are attached to this user, they will be associated with the `retained_user`. All events and user details of the `merged_user` will reflect on the `retained_user`. A merge event `MOE_USER_MERGE_EVENT` will be added to the `merged_user` (who will only have the MoEngage ID now). The `retained_user` will now have all the user, device, and event details of the `merged_user` along with its own existing details. A `MOE_USER_MERGED` event will be added to the `retained_user`. We will create a new user with that ID, but the MoEngage ID of this user will be different compared to the deleted user. The user will not be reachable. The maximum SLA is 30 minutes. In the user profile, all events of the last 30 days are moved from the merged user to the retained user. ### Delete User There are no rollback mechanisms for undoing the delete action. Once the delete request is processed, the user is deleted from MoEngage. No, the events corresponding to a user are not specifically deleted; only the user and the user attributes are deleted when the delete API request is processed. However, once the user is deleted from MoEngage, the events corresponding to the user will not be accessible. For example, if an event is used in a segmentation query, the deleted user who executed that event will not be added to the calculated segment or campaign. Navigate to **Segment** -> **Create Segment** on the MoEngage dashboard. Type the unique identifier for the deleted user (ID, MoEngage ID, phone number, email, or any unique identifier you have configured). If the user has been deleted (hard delete), you will not see any search results. For more information about searching users, refer to \[Search User in Segmentation]. ### Create Event Events in the payload need to be mapped to a given user who has executed the event. You must use the Customer ID to identify the events mapped to a customer. No, anonymous users can be tracked using MoEngage SDKs. Events in MoEngage are immutable, meaning events can only be created; they cannot be updated or deleted. ### Track Device No, you can pass only the device attributes mentioned above. Any additional custom attributes passed in the API payload are dropped during processing. The device will be created based on the Android platform, and the IDFV value passed in the API will be dropped. If the platform is iOS and a GAID value is passed, the device will be created with iOS, but the GAID attribute will be dropped. You can create a maximum of 1000 devices for a user. The user will be blocked if a 1001st device is created for the user. In such cases, the existing device will be deleted, and the new device will be added. ### MoEngage Streams The throughput and average volume of each API request depends on the volume of selected events captured into MoEngage. The default batch size (number of events for each API request) is 100. The retrial mechanism allows MoEngage to hit your provided endpoints in multiple attempts. In case a batch of events fails (anything other than a "2XX" response from the endpoint is considered failed), the entire batch is retried. MoEngage makes a total of three retry attempts with the following intervals: * **First Retry:** 30 seconds * **Second Retry:** 60 seconds * **Third Retry:** 120 seconds If you pause Streams, data is not collected for exports and hence cannot be replayed at a later date. No. Streams is primarily built to export your events in near real-time. Since user attributes in MoEngage are updated asynchronously, it is currently not possible to guarantee the latest values of user attributes in the exports. As of now, you cannot export data that occurred before configuring Streams. Once configured, you will start seeing data for each event from the moment you enable your exports. ### Bulk Import Yes, Track User API validations apply to the `Customer` payload type, and Create Event API validations apply to the `Event` payload type within the Bulk API request. Please implement an **exponential backoff** strategy for your requests. This ensures that your system gradually reduces request frequency during high-load periods, preventing data loss due to server-side errors. Receiving a **200 OK** status code only indicates that the users in your API payload have been successfully accepted for processing. It does not guarantee that the ingestion process is complete. While failures are rare, you can verify ingestion by searching for the users in the MoEngage Dashboard: Navigate to **Segment** > **Create Segment** > **Search for users** using their unique IDs. ### Trigger File Imports No, the schedule still remains the same as originally set up in the MoEngage Dashboard. ## Postman Collection We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/p593wcu/moengage-data-apis) to view the collection in Postman. # File Import Overview Source: https://moengage.com/docs/api/data/file-import-overview Fetch the processing status at both the import and file levels. The MoEngage File Imports API helps in proactively tracking the status of the Imports and the Files in an import without navigating to the MoEngage dashboard. ## Use Cases * Fetch the processing status of all imports for a given date range without navigating to the MoEngage dashboard. * Proactively alert about failures in automated campaigns. For example, if an automated campaign must run using the updated list of users ingested into MoEngage through the import option, but if the import fails for any reason, it may impact the reachability of your campaigns. Typically, you become aware of import failure only when navigating to the MoEngage dashboard or when you receive an email alert. However, with this API, you can track the status proactively even before the campaign is impacted. ## Endpoints The File Imports API is a collection of the following endpoints: * [Trigger File Imports API](https://www.moengage.com/docs/api/file-import/trigger-file-imports): Triggers scheduled file imports. * [Import Details API](https://www.moengage.com/docs/api/file-import/import-details): Fetches the status at an import level. * [Import File Run History API](https://www.moengage.com/docs/api/file-import/import-file-run-history): Fetches the file processing status of each file contained in an import. ## FAQs ### Trigger File Imports No, the schedule still remains the same as originally set up in the MoEngage Dashboard. ## Postman Collection Test these endpoints quickly by importing our Postman collection: * Trigger File Imports: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/u3yt8gn/moengage-file-imports-trigger-api?action=share\&creator=3182294) * Import Details: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/u3yt8gn/moengage-file-imports-trigger-api?action=share\&creator=3182294) * Import File Run History: [View in Postman](https://www.postman.com/moengage-dev/api-docs/collection/mzt9mgo/moengage-status-and-run-history-api?action=share\&creator=3182294) # Streams Source: https://moengage.com/docs/api/data/moengage-streams Forward user actions and campaign events to your API endpoint in near real-time using MoEngage Streams. With MoEngage Streams, you can configure your API endpoint, define the events you want to forward, and then view a stream of data flowing into your system. You can then utilize the data to enrich your data warehouses and recommendation systems. ## Use Cases for MoEngage Streams The following are a few popular use cases for Streams: * Enrich the central data warehouse with MoEngage events such as Notification Clicked Android, Email Clicked, SMS Clicked, and so on. * Forward the Conversion Events, such as Purchase, Song Played, Bill Payment Done, and so on, from MoEngage to the external Analytics tool. * Feed campaign interaction events from MoEngage to your recommendation system. * Export the notification interaction data from MoEngage to your machine learning system for optimizing the performance of your algorithms. * Send all user events present in MoEngage to an external data lake. ## Enable Streams for Your Account Contact your Customer Success Manager to get this enabled for your account. Note that Streams is available as a part of the Streams add-on. Streams can export data to your API endpoint or one of the partners integrated with MoEngage. ### Set Up Streams for Exporting Data to Your API Endpoint To export data from MoEngage to your servers, contact your MoEngage Customer Success Manager (CSM) or the Support team with the following information: 1. API endpoint to send the data. It can be something like `https://api.example.com/events`. 2. List of events that need to be sent to this API endpoint. A list of campaign events available for export is mentioned in the [next section](#campaign-interaction-events). 3. List of user attributes and device attributes that need to be sent to the API endpoint with each event. 4. If you need all campaign interaction events, we will export such events as mentioned in the [next section](#campaign-interaction-events). You can use the following template to raise a Streams enablement request: ```text theme={null} Hey! Please enable Streams for my Workspace. Workspace Region: DC-01/DC-02/DC-03/DC-04 Workspace Name: MyWorkspace Workspace ID: API Endpoint: [https://www.example.com/api?url_param1=vaue1](https://www.example.com/api?url_param1=vaue1) Headers: header1: value1 header2: value2 Authentication: Method: No auth/Basic Auth [Only for basic auth] Basic Auth username: "Username" [Only for basic auth] Basic Auth password: "Password" Events to export: All/List of events [Optional] List of events: List of events to export User properties to export: All/List of user properties [Optional] List of user properties: List of user properties to export ``` **Whitelist IPs** If your endpoints are in a Virtual Private Cloud (VPC) or not accessible publicly, you must whitelist [these](https://help.moengage.com/hc/en-us/articles/35329024618772-A-Guide-to-MoEngage-IP-Whitelisting-Mechanism#h_01JNGJBH0HCJAVHHP9MZZ8AYWM) MoEngage IPs depending on the region of your Workspace. ### Set Up Streams for Exporting Data to Partners With Streams, you can export data directly to integrated partners so that you can enrich your marketing/analytics activities on these platforms. As of now, Streams can export data to the following partners: * [Mixpanel](https://partners.moengage.com/hc/en-us/articles/4410027746836-Mixpanel#01FV1SH74TEQEBE0JVVAWJSWAS) * [Amplitude](https://partners.moengage.com/hc/en-us/articles/4409507678228-Amplitude-Audiences#h_01HJ11HMQGHRZT4GR260D27QK3) * [Segment](https://partners.moengage.com/hc/en-us/articles/12661517099284-MoEngage-Source) * [mParticle](https://partners.moengage.com/hc/en-us/articles/10223363585428-mParticle-Inbound) * [Rudderstack](https://partners.moengage.com/hc/en-us/articles/12718141249556-MoEngage-Source) Please follow partner-specific integration documents for setting this up. ## Campaign Interaction Events The following is a list of Campaign Interaction Events that MoEngage generates, which you will often need to be sent to your API endpoint: | Event Name | Event Code | Channel | | :---------------------------- | :------------------------------ | :---------------- | | Email Sent | `MOE_EMAIL_SENT` | Email | | Email Deferred | `MOE_EMAIL_DEFERRED` | Email | | Email Delivered | `MOE_EMAIL_DELIVERED` | Email | | Email Dropped | `MOE_EMAIL_DROP` | Email | | Email Bounced | `MOE_EMAIL_HARD_BOUNCE` | Email | | Email Soft Bounced | `MOE_EMAIL_SOFT_BOUNCE` | Email | | Email Opened | `MOE_EMAIL_OPEN` | Email | | Email Clicked | `MOE_EMAIL_CLICK` | Email | | Email Unsubscribed | `MOE_EMAIL_UNSUBSCRIBE` | Email | | Email Spam Complained | `MOE_EMAIL_SPAM` | Email | | SMS Sent | `SMS_SENT` | SMS | | SMS Delivered | `SMS_DELIVERED` | SMS | | Notification Received Android | `NOTIFICATION_RECEIVED_MOE` | Push | | Notification Clicked Android | `NOTIFICATION_CLICKED_MOE` | Push | | Notification Swiped Android | `NOTIFICATION_CLEARED_MOE` | Push | | Notification Sent iOS | `n_i_s` | Push | | Notification Clicked iOS | `NOTIFICATION_CLICKED_IOS_MOE` | Push | | Notification Received Web | `NOTIFICATION_RECEIVED_WEB_MOE` | Push | | Notification Clicked Web | `NOTIFICATION_CLICKED_WEB_MOE` | Push | | Connector Sent | `MOE_CONNECTOR_SENT` | Connector | | Card Sent | `MOE_CARD_SENT` | Cards | | Card Delivered | `MOE_CARD_DELIVERED` | Cards | | Card Viewed | `MOE_CARD_VIEWED` | Cards | | Card Clicked | `MOE_CARD_CLICKED` | Cards | | Mobile In-App Shown | `MOE_IN_APP_SHOWN` | Mobile In-Apps | | Mobile In-App Clicked | `MOE_IN_APP_CLICKED` | Mobile In-Apps | | Mobile In-App Closed | `MOE_IN_APP_DISMISSED` | Mobile In-Apps | | On-site Message Shown | `MOE_ONSITE_MESSAGE_SHOWN` | On-site Messaging | | On-site Message Clicked | `MOE_ONSITE_MESSAGE_CLICKED` | On-site Messaging | | On-site Message Closed | `MOE_ONSITE_MESSAGE_DISMISSED` | On-site Messaging | | User Entered Flow | `USER_ENTERED_FLOW` | Flows | | User Exited Flow | `USER_EXITED_FLOW` | Flows | | User Added to Control Group | `MOE_CAMPAIGN_CONTROL_GROUP` | All channels | * With the events above, the following event attributes will be exported by default: `campaign_id`, `campaign_name`, `campaign_type`, `campaign_channel`. * The following event attributes are not supported for export in streams currently: `email_subject`, `email_click_url`, `inapp_widget_clicked`, `onsite_message_url_clicked`. For more information on when the campaign events and attributes are tracked, refer to [Data Exports Glossary](https://help.moengage.com/hc/en-us/articles/15975781928468-Data-Export-Glossary). ## Authentication Methods Streams supports the following types of authentications: * **No auth** * **Basic Auth**: Streams supports the standard Basic Auth implementation. You must provide us with the username and password while configuring Streams. All data related to authentication is always encrypted in our systems. To support other authentication methods such as API Key, Bearer Token, and so on, you can communicate the same through the enablement ticket and provide us the Header key and static value to be passed. We will not be able to support dynamically refreshing API keys and tokens. ## API Request Format When Streams sends an event to your API endpoint, the request format will be as below: **Headers:** `"Content-Type":"application/json"` **Request Body:** ```json theme={null} { "app_name": "App Name", "source": "MOENGAGE", "moe_request_id": "moengage unique request id for each request", "events": [{ "event_name": "Notification Received Android", "event_code": "NOTIFICATION_RECEIVED_MOE", "event_uuid": "moengage unique id for each event", "event_time": 1580967474, "event_type": "CAMPAIGN_EVENT", "event_source": "MOENGAGE", "push_id": "recipient device’s push token", "uid": "", "event_attributes": { "campaign_id": "353df897hkbh67658", "campaign_name": "Name of the Campaign", "campaign_type": "Event Trigger", "campaign_channel": "Push" }, "user_attributes": { "moengage_user_id": "moe_internal_user_id", "user_attr_1": "user_attr_val1", "user_attr_2": "user_attr_val2" }, "device_attributes": { "moengage_device_id": "moe_internal_device_id", "device_attr_1": "device_attr_val1", "device_attr_2": "device_attr_val2" } }] } ``` ## Streams Data Glossary For the full list of updated events and attributes, refer to [Data Exports Glossary](https://help.moengage.com/hc/en-us/articles/15975781928468-Data-Export-Glossary). The keys in the API request and their description are: | Key | Description | | :------------------- | :----------------------------------------------------------- | | workspace name | Your workspace name in MoEngage. | | source | `MoEngage` to identify the requests coming from MoEngage. | | event\_name | Display Name of the event as seen on the MoEngage dashboard. | | event\_code | Raw event code as present in the MoEngage system. | | event\_uuid | Unique event identifier for de-duplication. | | event\_time | Time of event in UTC (epoch time in seconds). | | event\_type | `CAMPAIGN_EVENT` or `USER_ACTION_EVENT`. | | event\_source | Source identifier (value = `MoEngage`). | | push\_id | Push token (available for Push-related events). | | email\_id | Recipient email (available for Email-related events). | | mobile\_number | Recipient mobile number (available for SMS-related events). | | uid | MoEngage `customer_id` unique identifier. | | campaign\_name | Campaign name in MoEngage. | | campaign\_id | Campaign ID in MoEngage. | | event\_attributes | Dictionary of additional event attributes. | | campaign\_channel | Channel type: Push / Email / SMS. | | user\_attributes | Dictionary of additional user properties. | | moengage\_user\_id | MoEngage internal user ID. | | device\_attributes | Dictionary of additional device attributes. | | campaign\_type | Type: Periodic, Active, One-time. | | variation\_id | Present for campaign variations. | | locale\_id | Present for campaigns with multiple locales. | | locale\_name | Display name of the locale. | | parent\_campaign\_id | Identifier for localized campaign parents. | | parent\_flow\_id | Identifier for campaigns within a MoEngage Flow. | | parent\_flow\_name | Name of the MoEngage Flow. | ## Limitations Please be aware of the following constraints or limitations while integrating Streams with third-party apps. * We can send data to only one static endpoint where the access token or link has no expiry. We cannot integrate it on a dynamic endpoint where the access token is refreshed every few hours. * We cannot modify the body or key names while streaming the data from MoEngage. ## Sync Events from One MoEngage App to Another With MoEngage Streams, it is possible to sync your events from one MoEngage App to another. The following are some use cases: * **Cross-Product Promotions**: If you have teams across various product offerings, keeping two apps synced can help you cross-promote your products to upsell and increase conversion. * **Centralized Analysis**: Businesses with multiple apps can do cross-app analysis to unlock higher LTV, provide opportunities for cross-selling, and increase brand loyalty. ## Stream Events to Another MoEngage App Speak to your CSM to get your dedicated Streams endpoint for your destination app. Follow the enablement steps to configure the source App with the following details: * **Endpoint:** Use the dedicated MoEngage endpoint provided for your destination app. * **Authentication:** Enable Basic Auth. Use your destination app's **Workspace ID** as Username and its **Data API Key** as Password. * **Header:** Provide `"Content-Type" : "application/json"`. * **Events/Properties:** Select the list of events and user properties you want to stream. ## Frequently Asked Questions The throughput and average volume of each API request depends on the volume of selected events captured into MoEngage. The default batch size (number of events for each API request) is 100. In case a batch of events fail (any non-2XX response), the entire batch is retried. In total, three retry attempts are made with intervals of 30, 60, and 120 seconds. No. If you pause Streams, data is not collected for exports and cannot be replayed at a later date. No. Streams is built for near real-time event export. Since user attributes are updated asynchronously, we cannot guarantee the latest values in the export. No. You can only export data generated after the Streams configuration is enabled. # Device Opt-out Source: https://moengage.com/docs/api/device/device-opt-out /api/data/data.yaml post /devices/manage This API blocks or unblocks specific devices from receiving push notifications triggered from MoEngage. To prevent push notifications from reaching a specific user or all devices associated with a user, call the API to block them. This is useful for reasons such as device theft or fraudulent activity. For example, if a device is stolen, you can use this API to block it in MoEngage, ensuring that any scheduled push notifications with sensitive content do not get delivered. You can also use the API to unblock a device if it is recovered. #### Rate Limit The rate limit is 1000 API requests per minute. # Track Device Source: https://moengage.com/docs/api/device/track-device /api/data/data.yaml post /device/{app_id} This API adds or updates devices and device properties in MoEngage. You can create a new device for an existing user, create new device properties for an existing user, or update the device properties of the existing user. #### Rate Limit A single API request contains one or more device updates. Maintain a rate limit of 10,000 device updates per minute.. # Email Subscription Overview Source: https://moengage.com/docs/api/email-subscription/email-subscription-overview Manage user email resubscription, opt-in status, and category preferences. The MoEngage Email Subscription Management APIs allow you to update email preferences for your users directly within the MoEngage platform. This suite enables you to synchronize resubscription status with external Email Service Providers (ESPs) and manage granular category-level opt-ins to ensure compliance and a better user experience. ## Endpoints The Email Subscription API consists of the following endpoints: * [Bulk Resubscribe Users](/api/resubscribe/bulk-resubscribe-users): Resubscribes users and optionally updates ESP suppression lists. * [Update User Email Opt-in Preferences](/api/opt-in-management/update-user-email-opt-in-preferences): Updates overall opt-in status and category-specific preferences. ## API Capabilities | Feature | Bulk Resubscribe | Opt-in Management | | ----------------------- | ---------------------- | ----------------- | | **Sync with ESP** | ✓ (SendGrid supported) | ✗ | | **Category Management** | ✗ | ✓ | | **Bulk Processing** | ✓ (Up to 100 users) | ✗ (Single User) | | **Async Processing** | ✓ | ✗ | ## Implementation Notes **ESP Support:** The Resubscription API currently supports **SendGrid** only. When `update_esp` is set to `true`, MoEngage automatically removes the email addresses from your SendGrid suppression list. **Identity Management for Opt-in:** * **PII Tokenization:** You must pass the `customer_id`. MoEngage uses this to locate the user as the email ID is not stored. * **PII Encryption:** Pass either the `customer_id` or the decrypted `email_id`. If only the email ID is passed, all users associated with that email will be updated. ## FAQs ### Resubscription We will automatically call the ESP to remove the recipient email addresses sent in the request from their suppression list. This attribute is configured in the User Attribute that stores user’s email address field in the General Settings for the Email channel. You can either use the “Email Standard” attribute that MoEngage uses by default or configure any other custom attribute of your choice to store the email address of your users. This attribute is available in the User Profile for each user. The Resubscription API will use this attribute to look for the users mapped to the email addresses in the recipient list and update their subscription status. The Current Connector field in Email -> General Settings has the information about which ESP is used. The Resubscription API will use this information to update the suppression list in the ESP. If any other ESP is sent in the request or configured as the default connector, then only the Unsubscribe standard attribute in MoEngage will be updated to false, and the ESP will not be updated (only Sendgrid ESP is supported for the Resubscription API). When the ESP is changed in the Email General Settings, it takes up to 15 minutes for the settings to get reflected. If a resubscription request is executed within this time frame, the older settings will get picked. For example, if the ESP is changed from Amazon to SendGrid and a resubscription request is performed within 15 minutes of updating the settings, the ESP would still be Amazon. The unsubscribe flag will get updated in the MoEngage Dashboard alone. The Data API updates only the unsubscribe attribute in MoEngage. The Resubscribe Email API additionally syncs with your ESP (SendGrid) to remove the email from their suppression list. ### Opt-in and Categories The user attribute specified in the General Settings of email will be used to search for users matching the provided email ID. Email ID is given higher priority, and MoEngage finds all users with the same email ID and updates them with the passed opt-in status value. However, if you have requested not to carry forward the opt-in status or unsubscribe information across profiles with the same email ID, MoEngage picks the customer\_id and uses it to update the opt-in status. Yes, they are carried forward by default. If User A and B have the same email ID and MoEngage received consent from A, both A and B are marked as double-opted in. This can always be controlled. To do so, contact the MoEngage team. If the API payload has even one category that is not active or present in your workspace, MoEngage throws an error and drops the request. No, it is not mandatory. If required, you can always track this at the global level. Suppose API key rotation is practiced, and the workspace has more than one active API key for a smoother transition. In that case, you can use any active API key associated with Email Double optin for authorization purposes. Multi AP Ikey Whenever a user's opt-in status is updated using this API, the Resubscribe API, the Update Subscription Preference API, or via the end-user interaction, MoEngage raises an event called Email Optin Status Updated with the necessary information. * If you use PII Tokenization for your emails, ensure you pass the user ID when calling the Email Opt-in Management API. MoEngage uses this user ID to locate the user and update their opt-in status. Passing the email ID is ineffective in this case, as MoEngage does not store it. * If you use PII Encryption to send emails, ensure you pass either the user ID or the decrypted email ID. MoEngage uses this information to locate the associated user and update their opt-in status, or to update the opt-in status of all users having that email ID. ## Postman Collections Test these subscription APIs immediately using our Postman collection. View Postman Collection → [**Resubscribe API**](https://www.postman.com/moengage-dev/api-docs/collection/xt2ptnc/moengage-resubscribe-api) and [**Email Optin Management**](https://www.postman.com/moengage-dev/api-docs/request/fcc8l9m/email-optin-managment?tab=overview). # Email Templates (V1) Overview Source: https://moengage.com/docs/api/email-templates-1/email-templates-1-overview Define, reuse, update, and manage email templates created outside the MoEngage ecosystem effortlessly. The MoEngage Email Template API allows marketers to define, reuse, update, and manage email templates created outside the MoEngage ecosystem with ease. The templates created and updated using these APIs are supported for the Custom HTML Editor (Froala Editor) and not the Drag and Drop Editor. ## Endpoints The Email Template API (V1) is a collection of the following endpoints: * [Create Email Template](/api/email-templates/create-email-template-v1): Creates an email template. * [Update a Specific Email Template](/api/email-templates/update-specific-template): Updates an email template specified by its Template ID. * [Bulk Create/Update Email Template](/api/email-templates/bulk-createupdate-templates): Creates and updates email templates in bulk. * [Get a Specific Email Template](/api/email-templates/get-specific-template): Fetches an email template using its Template ID. * [Get all Email Templates](/api/email-templates/get-all-templates): Fetches all the email templates in your MoEngage account. ## FAQs ### Create Email Template You can access templates created using the Create Email Template API in the My Saved Templates tab during the second step of campaign creation in the MoEngage Dashboard, as illustrated in the image below: alt text ### Update a Specific Email Template The update request will overwrite the existing template with the template shared in the update request. If the update request does not have some of the fields that the created template had, the updated template will not have them too. For example, if you do not pass any attachments in the update request, the updated template will not have any attachments, even if it had attachments while it was created. ### Bulk Create/Update Email Template In the case of an update, the template to be updated is identified using its template id. It is mandatory to pass the id field in the required for an update template request. Otherwise, it will be treated as a create template request. ### Get a Specific Email Template The error description contains the following message in such a case: “*Template for given template id is archived*”. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/dc04rwi/moengage-content-email-template-apis-v2?action=share\&creator=3182294) # Email Templates (V2) Overview Source: https://moengage.com/docs/api/email-templates-2/email-templates-2-overview Define, reuse, update, and manage email templates created outside the MoEngage ecosystem effortlessly. The MoEngage Email Template API allows marketers define, reuse, update, and manage email templates created outside the MoEngage ecosystem effortlessly. You can create multiple versions of the same template and mark whether they can be used in the campaigns that are active currently. Users can create templates using the Create Email Template API and update them using the Update Email Template API or edit them in the MoEngage dashboard (provided they have the specific editing permissions for the templates allowed for their role). The templates created and updated using these APIs are supported for the Custom HTML Editor (Froala Editor) and not the Drag and Drop Editor. ## Endpoints The Email Template API (V2) is a collection of the following endpoints: * [Create Email Template API](/api/email-templates/create-email-template-v2): Creates an email template. * [Update Email Template API](/api/email-templates/update-email-template): Updates an email template specified by its Template ID. * [Search Email Template API](/api/email-templates/search-email-template): Fetches an email template using its Template ID or other filters like template name, template version, and so on. It can also list all the email templates created in MoEngage using the Create Email Template API. ## FAQs ### Create Email Template API You can access templates created using the Create Email Template API in the Imported API Templates tab in the second step of campaign creation in the MoEngage Dashboard, as illustrated in the image below: alt text Yes, you can create multiple templates with the same name, provided they have different versions. # Bulk Create/Update Templates Source: https://moengage.com/docs/api/email-templates/bulk-createupdate-templates /api/email-templates-1/email-templates-1.yaml put /bulk/email-templates This API creates or updates email templates in bulk. You can create or update up to 50 templates in a single request. #### Rate Limit The rate limits are at the workspace level, and a maximum of 1000 (sum of all the API requests per workspace) requests are allowed for a workspace per minute. # Create Email Template (V1) Source: https://moengage.com/docs/api/email-templates/create-email-template-v1 /api/email-templates-1/email-templates-1.yaml post /email-templates This API creates an email template in MoEngage. You can use this API to upload templates created outside the MoEngage ecosystem to MoEngage and use them for campaign creation on the MoEngage dashboard. #### Rate Limit The rate limits are at the workspace level, and a maximum of 1000 (sum of all the API requests per workspace) requests are allowed for a workspace per minute. # Create Email Template (V2) Source: https://moengage.com/docs/api/email-templates/create-email-template-v2 /api/email-templates-2/email-templates-2.yaml post /custom-templates/email This API creates an email template in MoEngage. You can use this API to upload templates created outside the MoEngage ecosystem to MoEngage and use them for campaign creation. The uploaded templates can be edited in the Froala editor (custom HTML editor) on the MoEngage dashboard. #### Rate Limit The rate limit is 100 RPM. You can upload a maximum of 10000 templates per channel. # Get All Templates Source: https://moengage.com/docs/api/email-templates/get-all-templates /api/email-templates-1/email-templates-1.yaml get /email-templates This API fetches the list of all the email templates available in your MoEngage account. #### Rate Limit The rate limits are at the workspace level, and a maximum of 1000 (sum of all the API requests per workspace) requests are allowed for a workspace per minute. # Get Specific Template Source: https://moengage.com/docs/api/email-templates/get-specific-template /api/email-templates-1/email-templates-1.yaml get /email-templates/{id} This API fetches an email template using its template ID. #### Rate Limit The rate limits are at the workspace level, and a maximum of 1000 (sum of all the API requests per workspace) requests are allowed for a workspace per minute. # Search Email Template Source: https://moengage.com/docs/api/email-templates/search-email-template /api/email-templates-2/email-templates-2.yaml post /custom-templates/email/search This API searches the email templates created in your MoEngage account. **Note** We are introducing mandatory pagination, effective November 15, 2025, all calls to this API must include the following two parameters: * `page`: The page number of the results you wish to fetch. * `entries`: The number of templates to return per page, with a maximum value of 15. Please update all integrations to include these parameters. API requests submitted without them after the effective date will result in an error and fail to execute. #### Rate Limit The rate limit is 100 Requests Per Minute. # Update Email Template Source: https://moengage.com/docs/api/email-templates/update-email-template /api/email-templates-2/email-templates-2.yaml put /custom-templates/email This API updates an email template by specifying its external template ID. You can specify whether the updated version of the template can be used in active campaigns in the request. #### Rate Limit The rate limit is 100 Requests Per Minute. # Update Specific Template Source: https://moengage.com/docs/api/email-templates/update-specific-template /api/email-templates-1/email-templates-1.yaml put /email-templates/{id} Updates an existing email template by specifying its template ID in the path. #### Rate Limit The rate limits are at the workspace level, and a maximum of 1000 (sum of all the API requests per workspace) requests are allowed for a workspace per minute. # Track Event Source: https://moengage.com/docs/api/event/track-event /api/data/data.yaml post /event/{Workspace_ID} This API tracks the actions of a user. * If you have [Portfolio](https://help.moengage.com/hc/en-us/articles/40394603054100-Portfolio) enabled for your workspace, you need to pass project\_code in the API endpoint. This identifies which project a user or event belongs to. For more information, refer to [Portfolio: Data Ingestion and Management](https://help.moengage.com/hc/en-us/articles/40358246598804-Portfolio-Data-Ingestion-and-Management). * MoEngage does not accept any future dated events. #### Rate Limit A single API request contains one or more events. Maintain a rate limit of 30,000 events per minute. # Track Experience Events Source: https://moengage.com/docs/api/events/track-experience-events /api/personalize-experience/personalize-experience.yaml post /experiences/events This API tracks impressions (shown) and user interactions (clicked) for accurate experience reporting. To report an impression or click for your experience via API, use the following endpoint. # Fetch Experience Source: https://moengage.com/docs/api/experiences/fetch-experience /api/personalize-experience/personalize-experience.yaml post /experiences/fetch This API receives data on active personalization experiences. You can fetch data for one or more server-side experiences by using the **experience_key** field. MoEngage will evaluate targeting rules and in-session attributes automatically and return the correct variation for the user. Typically, you would make this call as part of your larger page and content rendering pipeline. # Fetch Experience Metadata Source: https://moengage.com/docs/api/experiences/fetch-experience-metadata /api/personalize-experience/personalize-experience.yaml get /experiences/metadata This API fetches a list of currently Active, Scheduled, and Paused experiences within a workspace. # Import Details Source: https://moengage.com/docs/api/file-import/import-details /api/data/data.yaml post /fileimports/import/status This API fetches the status at an import level. It can fetch the status of multiple imports but not the status of the files within the import. #### Rate Limit You can create 50 requests per minute. # Import File Run History Source: https://moengage.com/docs/api/file-import/import-file-run-history /api/data/data.yaml post /fileimports/import/run/history This API fetches the file processing status of each file contained in an import. The API request must contain either the import_name or the import_id. If you are not sure of the import_id or the import_name, you can use the [Import Details API](https://www.moengage.com/docs/api/file-import/import-details) to get the import details, which can be further used in the Import File Run History API. #### Rate Limit You can create 50 requests per minute. # Trigger File Imports Source: https://moengage.com/docs/api/file-import/trigger-file-imports /api/data/data.yaml post /fileimports/trigger/{schedule_id} This API triggers scheduled file imports. You can trigger periodic imports to run using this API if the import has not expired and is in any of the following states- Scheduled, Successful, Partially Successful, and Failed. #### Rate Limit You can trigger this API once in every five minutes for a specific schedule\_id. A Bad request response (400) response will be sent if this is exceeded. # Add Users to File Segment Source: https://moengage.com/docs/api/file-segments/add-users-to-file-segment /api/custom-segments/custom-segments.yaml put /v2/custom-segments/file-segment/add-users This API adds a list of users from a CSV file to an existing file segment. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # Create File Segment Source: https://moengage.com/docs/api/file-segments/create-file-segment /api/custom-segments/custom-segments.yaml post /v2/custom-segments/file-segment This API creates a new file segment from a CSV file URL. * If your file is private, you should whitelist [these IPs](https://help.moengage.com/hc/en-us/articles/35329024618772-A-Guide-to-MoEngage-IP-Whitelisting-Mechanism#h_01JNGJNR5F141E7KRK89YW1X8H) to provide access only to MoEngage for the file. * This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. #### Rate Limits | Rate Limit Name | Rate Limit | | :-------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | | total active segment | The limit of the total number of active segments at a time for a client is 1000. | | file\_segment ops per hour | The total number of file segment operations (create/add/remove) per hour per client allowed is 10. | | file\_segment ops per day | The total number of file segment operations (create/add/remove) per day per client allowed is 100. | | file\_segment users per day | The total number of users uploaded via the File segment is limited to 2 million per day. (This limit is customizable, contact the MoEngage Support team). | | file\_size\_limit | The size of the file from which the segment is created/updated. For each request, the file size limit is 150 MB. | **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. * The limit of 1000 file segments is calculated only for the file segments that are active. Most of our customers utilize only 30-40% of this limit at any given point. #### CSV File Requirements * The attribute names should be separated by new lines. * CSV should be a single column and less than 150MB. * Values should not end with a comma (e.g., `abcd` not `abcd,`). * Values should not have duplicates or special characters (e.g., `abcd` not `"abcd"` or `a#bc`). * File should not have empty rows or columns. * A user attribute value must uniquely identify a single user. * [Sample File Link](https://app-cdn.moengage.com/assets/Sample_GAIDs.csv) #### Segment Processing and Availability As soon as the request is received at the MoEngage system, MoEngage creates a segment with zero users. After this, the file is processed and users are added to the segment. If the created segment is queried in between the file processing, it will show zero or partial user count. # Remove Users from File Segment Source: https://moengage.com/docs/api/file-segments/remove-users-from-file-segment /api/custom-segments/custom-segments.yaml put /v2/custom-segments/file-segment/remove-users This API removes a list of users from a CSV file from an existing file segment. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # Replace Users from File Segment Source: https://moengage.com/docs/api/file-segments/replace-users-from-file-segment /api/custom-segments/custom-segments.yaml put /v2/custom-segments/file-segment/replace This API replaces all users in an existing file segment with a new list of users from a CSV file. **Notes:** * This API drops all existing users from the segment and adds the new users provided in the File URL. * Only the newly added users are counted towards the daily file segment user limit. * This API does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # Create Filter Segment Source: https://moengage.com/docs/api/filter-segments/create-filter-segment /api/custom-segments/custom-segments.yaml post /v3/custom-segments This API creates a new segment based on a set of filter conditions. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. #### Generate Request from Dashboard To simplify the request generation, MoEngage has added an option in the dashboard where you can specify filters as per your requirement and generate the payload. 1. Login to the MoEngage dashboard. 2. Click **Test & Debug** at the lower left in the side panel. 3. Click **Segment Payload**. 4. Specify the name for your segment payload and provide the required filters. 5. Click **Generate payload** button. #### Rate Limit The rate limit is 50 request/minute, 200 requests/hour, and 1000 requests/day. # Get Segment by ID Source: https://moengage.com/docs/api/filter-segments/get-segment-by-id /api/custom-segments/custom-segments.yaml get /v3/custom-segments/{id} This API fetches a specific segment (File or Filter) by its ID. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. #### Rate Limit The rate limit is 100 requests/minute, 1000 requests/hour, and 4000 requests/day. # List Segments Source: https://moengage.com/docs/api/filter-segments/list-segments /api/custom-segments/custom-segments.yaml get /v3/custom-segments This API lists all segments. You can optionally filter segments by an exact name match. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. #### Rate Limit The rate limit is 50 request/minute, 200 requests/hour, and 1000 requests/day. # Update Filter Segment Source: https://moengage.com/docs/api/filter-segments/update-filter-segment /api/custom-segments/custom-segments.yaml patch /v3/custom-segments/{id} This API updates an existing filter segment by its ID. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # GDPR or CCPA Overview Source: https://moengage.com/docs/api/gdpr-ccpa/gdpr-ccpa-overview Manage user data privacy rights and erasure requests to ensure GDPR and CCPA compliance. The MoEngage GDPR or CCPA API ensures that all user data rights are respected and managed for compliance with the General Data Protection Regulation (GDPR) and the California Consumer Privacy Act (CCPA). This API allows you to submit data requests, including the permanent erasure of personal data for specific users. For detailed implementation guides on how MoEngage handles these regulations, refer to our [GDPR Implementation](https://help.moengage.com/hc/en-us/articles/360000878126-GDPR) and [CCPA Implementation](https://help.moengage.com/hc/en-us/articles/360052917232-CCPA) documentation. ## Endpoint The GDPR or CCPA API consists of the following endpoint: * [Submit a Data Request](/api/gdpr/submit-a-gdprccpa-data-request): Create or update user rights (e.g., erasure requests). ## FAQs No. Multiple users cannot be deleted using this API in a single payload. You must send individual requests for different users unless they share the same email identity (see note above). If multiple users have the same email ID and that email ID is passed in the erasure request, MoEngage will delete **all** users associated with that specific email ID. The maximum payload size is 128 KB. If this limit is exceeded, a 413 error response will be sent. ## Postman Collections Test your compliance workflows using our pre-configured Postman collection. [View Postman Collection →](https://www.postman.com/moengage-dev/api-docs/request/j4fwuwk/gdpr-ccpa-api?action=share\&source=copy-link\&creator=9636111) # Submit a GDPR / CCPA Data Request Source: https://moengage.com/docs/api/gdpr/submit-a-gdpr-ccpa-data-request /api/gdpr-ccpa/gdpr-ccpa.yaml post /opengdpr_requests/{appId} GDPR or CCPA API ensures all the rights of users are created or updated for GDPR or CCPA compliance. You can erase the personal data of specific users as defined under GDPR using the Erase API. For more details on compliance with MoEngage, refer to [GDPR-Implementation](https://help.moengage.com/hc/en-us/articles/360000878126-GDPR) and [CCPA-Implementation](https://help.moengage.com/hc/en-us/articles/360052917232-CCPA). **Warning:** Multiple users **cannot** be deleted using this API in a single payload. If an email ID associated with multiple users is passed for an erasure request, **all** associated users will be deleted. #### Rate Limit The maximum limit per request is **100 KB**. The maximum payload size is **128 KB**. # Get Campaign Meta Source: https://moengage.com/docs/api/get-campaign-details/get-campaign-meta /api/campaigns/campaigns.yaml post /campaigns/meta This API retrieves campaign details and reachability information for scheduled campaigns. #### 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. # Get Child Campaigns Source: https://moengage.com/docs/api/get-campaign-details/get-child-campaigns /api/campaigns/campaigns.yaml post /campaigns/{parent_campaign_id}/executions 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. #### 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** * 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. # Search Campaigns Source: https://moengage.com/docs/api/get-campaign-details/search-campaigns /api/campaigns/campaigns.yaml post /campaigns/search 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. #### 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) **API Enablement:** If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. # Create In-app Template Source: https://moengage.com/docs/api/in-app-templates/create-in-app-template /api/in-app-templates/in-app-templates.yaml post /custom-templates/inapp This API creates an In-app template in MoEngage. You can use this API to upload templates created outside the MoEngage ecosystem to MoEngage and use them for campaign creation. **Information** Only self-handled and HTML template types are supported. # In-app Templates Overview Source: https://moengage.com/docs/api/in-app-templates/in-app-templates-overview Create, search, and update In-app templates (Self-Handled and HTML). The MoEngage In-app Templates API allows you to seamlessly manage In-app templates within the MoEngage platform. This API enables you to upload templates created outside the MoEngage ecosystem—supporting both **Self-Handled** and **HTML** types—so they can be used for campaign creation. With these endpoints, you can create versions of your templates, search through your existing library using various filters, and choose whether updates to a template should automatically reflect in your active campaigns. ## Endpoints The In-app Templates API is a collection of the following endpoints: * [Create In-app Template](/api/in-app-templates/create-in-app-template): Creates a new In-app template (Self-Handled or HTML). * [Update In-app Template](/api/in-app-templates/update-in-app-template): Updates an existing template. * [Search In-app Templates](/api/in-app-templates/search-in-app-templates): Finds templates using filters like name, source, type, or creator ID. ## FAQs Currently, the API supports **SELF\_HANDLED** (JSON-based) and **INAPP\_HTML** template types. When using the **Update In-app Template** API, set the `update_campaigns` flag to `true`. This will update all running campaigns currently using that template to the latest version. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/wada9u5/moengage-in-app-api?action=share\&source=copy-link\&creator=28342601) # Search In-app Templates Source: https://moengage.com/docs/api/in-app-templates/search-in-app-templates /api/in-app-templates/in-app-templates.yaml post /custom-templates/inapp/search This API searches the In-app templates created in your MoEngage account. **Mandatory Pagination** We are introducing mandatory pagination, effective **November 15, 2025**. All calls to this API must include the following two parameters: * `page`: The page number of the results you wish to fetch. * `entries`: The number of templates to return per page, with a maximum value of *15*. Please update all integrations to include these parameters. API requests submitted without them after the effective date will result in an error and fail to execute. # Update In-app Template Source: https://moengage.com/docs/api/in-app-templates/update-in-app-template /api/in-app-templates/in-app-templates.yaml put /custom-templates/inapp This API updates an In-app template as per your requirements. # Inform Overview Source: https://moengage.com/docs/api/inform/inform-overview Send a transactional alert to a user on one or more channels. The MoEngage Inform API allows you to send a transactional alert to a user on one or more channels using a pre-configured Alert ID or Alert Reference Name. ## Supported Scenarios Transactional Alerts are designed for critical user communications, including: * Order/Booking/Purchase confirmations * Shipping/Delivery confirmations and updates * Security and account alerts * Password resets * OTP (one-time password) * User invitations and shares * User inaction related to previous transactions * Fraud prevention/security alerts This API sends notifications to all the channels simultaneously for a specified Live Alert. You can use it to do the following: * Send a transactional message on a single channel like SMS or Email or Push. * Send transactional messages on multiple channels. ## Endpoint The Inform API consists of the following endpoint: * [Inform API](/api/transactional-alerts/send-transactional-alert) ## Glossary The following is a list of terminology that you will encounter when using the Inform API. | Term | Definition | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Alert ID** | This is the unique identifier for an Alert. This field will be used to identify the Alert configured in the MoEngage Dashboard that contains the template for the notifications to be sent to the user. | | **Alert Reference Name** | This field is used to identify the Alert using your reference Name and can be used to identify the alert as an alternative to Alert ID. | | **Test Alert ID** | When creating an Alert, you can test it on an external console and MoEngage provides a unique identifier called Test Alert ID for this purpose. | | **Test Alert Reference Name** | Test Alert Reference Name is configured while adding the alert on the Dashboard to send this Test Alert request to an external console. | ## Live vs. Test Environments Ensure you are using the correct ID and Endpoint for your environment. | Feature | Live Alerts | Test Alerts | | :------------- | :------------------------------------------------ | :-------------------------------------------------------- | | **Identifier** | Use the **Alert ID** for published alerts. | Use the **Test Alert ID** for testing. | | **Logs** | Logs are available in the **Alert Info** section. | Logs are available in the **3rd Step** of Alert Creation. | | **Endpoint** | `https://api-0{dc}.moengage.com` | `https://sandbox-api-0{dc}.moengage.com` | ## How Does Inform API Work and Respond? Inform API works in two steps as described below: 1. A check is performed to verify if the API request received for Inform is valid. 2. If valid, the second process is to resolve the content and send a message using the partner. ### Response Codes The response codes are shared in **wxyzab** format as described below: * **w** - Status (failures are indicated with 1 and success is indicated with 2). * **x** - Category of the error. * **y** - Request is considered for parallel request (parallel requests is indicated with 0 and fallback requests are indicated with 1). * **z** - Can this request be retried by you(0 indicates it cannot be retried with same details). * **ab** - Reason details for the error. Below are the Category details: | Category Code | Details | | :------------ | :-------------------------------- | | 1 | Unauthorized | | 2 | Bad Request | | 4 | Internal Server Error / Ratelimit | The Reason details are given below with each Reason Code holding specific meanings: | Reason Code | Details | | :---------- | :-------------------------- | | 1 | Invalid Credentials | | 2 | Invalid Alert ID | | 3 | Missing Transaction ID | | 4 | Duplicate Transaction ID | | 5 | Long Transaction ID | | 6 | Invalid Payload | | 7 | Personalisation Attribute | | 9 | Internal Server Error | | 10 | Rate Limit | | 11 | Personalisation Failed | | 12 | Invalid Recipient details | | 13 | Vendor configuration errors | | 14 | Vendor not available | | 15 | Vendor Payload Rejection | | 16 | Unexpected Error Occurred | | 17 | Invalid Origin Source | ## Payload Errors Before Accepting the API Request The list of the payload errors that can occur before accepting the API request and the equivalent response codes to be shared under HTTP status code **4xx** for different scenarios across each functionality is given below: | Payload Errors | Description | Scenarios | Response Codes | Resolution | | :--------------------------------------- | :----------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------- | | **Authorization Failure** | This error occurs when invalid authorization details such as App Key (Workspace ID) or Password are shared. | No Auth values passed.
Incorrect Auth Values Passed
Incorrect Password shared.
No Auth & No Key Passed
No App key shared / Empty App Key
Incorrect App Key shared | `{"message": "Authorization Failed", "err_code": "UNAUTHORIZED"}` | Recheck the authorization details listed in Settings / Check if you passed the Test Alert ID on Live Endpoint. | | **Invalid Alert ID** | This error occurs when an invalid Alert ID or external reference name is shared. | Missing Alert ID
Alert ID \<24 characters
Alert ID > 24 Characters
Invalid Alert ID | `{"message": "Invalid Alert ID", "err_code": "BAD_REQUEST", "status_code": 120002}` | Recheck the Alert ID or external reference name listed on the Info page. | | **Invalid Transaction ID** | This error occurs when the Transaction ID is not shared. | Missing Transaction ID | `{"message": "Invalid Transaction ID", "err_code": "BAD_REQUEST", "status_code": 120003}` | Share the transaction ID using the key name `transaction_id` as part of the API Call. | | **Long Transaction ID** | This error occurs when the Transaction ID is invalid. | Long Transaction ID | `{"message": "Long Transaction ID", "err_code": "BAD_REQUEST", "status_code": 120004}` | Reduce the length of the Transaction ID to 50 characters. | | **Duplicate Transaction ID** | This error occurs when the currently shared Transaction ID matches the previous one in the last 5 minutes. | Duplicate Transaction ID | `{"message": "Duplicate Transaction ID", "err_code": "DUPLICATE_REQUEST_RECEIVED", "status_code": 120105}` | Add a unique Transaction ID. | | **Invalid Payload** | This error occurs when the payload is in incorrect JSON format or when incorrect Channel details are shared. | Invalid JSON / Invalid Class
Channel Attribute is incorrect / Channel details missing | `{"message": "Invalid Payload", "err_code": "BAD_REQUEST", "status_code": 120006}` | Recheck the JSON format and the Channel details.
Sample payload is available on our Info page. | | **Personalisation Attribute Max length** | This error occurs when the Personalization Attribute length is greater than 1500 characters. | - | `{"message": "Personalisation attribute limit exceeded - {x}", "err_code": "BAD_REQUEST", "status_code": 120007}` | Reduce the length of the Personalization Attribute to 1500 characters / payload size of \<100 KB | | **Invalid Recipient** | This error occurs when the recipient details like mobile number or email address are invalid. | - | `{"message": "Invalid Recipient", "err_code": "BAD_REQUEST", "status_code": 120012}` | Recheck the recipient details in the API call or the User Profile. | | **Internal Server Error** | This error occurs when MoEngage is not able to resolve the API request. | - | `{"message": "Unexpected error occurred", "err_code": "Internal Server Error", "status_code": 140109}` | Retry using the same API call with a different Transaction ID. | | **Rate Limit** | This error occurs when you cross the Rate Limit. | - | `{"message": "Too many requests", "err_code": "Rate Limit", "status_code": 140110}` | Make API calls within the Rate Limit. | ## Payload Errors After Accepting the API Request Alerts can be configured for parallel/sequential fallback as described below: * **Parallel**: For parallel requests, the payload information of success/failure requests should be added at each channel level. * **Sequence**: For fallback requests, the payload information of success/failure requests should be added for the first channel, and other channels, info should be shared over streams. The list of the payload details that can occur after accepting the API request and the equivalent response codes to be shared under HTTP status code \*\*200/429 \*\*for different scenarios across each functionality is given below: | Payload Errors | Description | Response Codes | Resolution | | :---------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------- | | **Personalisation Failed** | This error occurs when the required Personalization attributes are not shared in the API call or User Profile doesn't have these values. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Personalisation Failure - {{attribute name}}", "err_code": "BAD_REQUEST", "status_code": "120011 / 121011"}}` | Either share the valid Personalization attributes in the API call or update the User Profile with the required values. | | **Invalid Recipient details** | This error occurs when the recipient details like mobile number or email address are invalid. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Invalid Recipient", "err_code": "BAD_REQUEST", "status_code": "120012 / 121012"}}` | Recheck the recipient details in the API call or the User Profile. | | **Internal Errors** | This error occurs when MoEngage is not able to resolve the API request or channel level details. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Unexpected error occurred", "err_code": "Internal Server Error", "status_code": "140109 / 141109"}}` | Retry using the same API call with a different Transaction ID. | | **Vendor Errors** | This error occurs when the vendor configuration is invalid. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Invalid Vendor Configuration", "err_code": "Vendor Error", "status_code": "150013 / 151013"}}` | Recheck the vendor configuration in MoEngage for SMS, Push, and Email. | | **Vendor Unavailable** | This error occurs when the vendor is not available. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Vendor not available", "err_code": "Vendor Error", "status_code": "150014 / 151014"}}` | NA/MoEngage will retry up to 5 times to submit the message to the vendor. | | **Vendor Rejected** | This error occurs when the vendor rejects the Payload. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Rejected by Vendor with error - {{error from vendor}}", "err_code": "Vendor Error", "status_code": "150015 / 151015"}}` | Resolve the error sent by the vendor and then make the API call. | | **Vendor Accepted** | This is sent as response when vendor accepts the request. | `{"message": "Successfully Received", "Request_ID": 122323, "SMS": {"message": "Successfully sent", "err_code": "NA", "status_code": 200000}}` | - | ## FAQs A request is deemed a duplicate in the following cases: * It is received within 5 minutes of a previously successful request containing the same transaction\_id * It is received within 5 minutes of a previous request which is ‘In Progress’ (being processed) and contains the same transaction\_id Duplicate requests are dropped and not reprocessed. When the vendor does not accept requests from MoEngage, MoEngage retries every request a maximum of five times with 200ms exponential backoff. Alert logs are stored for up to 30 days for every Alert in MoEngage. This error occurs when you hit the live alert ID at the sandbox endpoint. For every alert, there are 2 IDs: one is live, and another is Test; the same behavior can be seen for alerts created on the test environment of the MoEngage Dashboard as well. Test Alert ID can be picked up by editing the Alert and going to the 3rd page. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [View in Postman](https://www.postman.com/moengage-dev/api-docs/collection/n3e0uj9/moengage-inform-api).  # API Overview Source: https://moengage.com/docs/api/introduction Explore MoEngage REST APIs for managing user data, campaigns, segments, templates, and integrations. **Beta** We are refining the new API docs. While exploring them, you may encounter minor issues. We appreciate your patience as we finalize the content. The [existing API docs](https://developers.moengage.com/hc/en-us/categories/4404541620756-API) will be accessible until the transition is complete. ## API Categories Create and update users, track events, manage devices, and import data in bulk. Create and trigger business events to power automated campaigns. Manage templates, content blocks, recommendations, coupons, and catalogs. Create and manage Push and Email campaigns programmatically. Create and manage file-based, filter-based, and cohort-synced user segments. Manage email subscriptions and subscription category preferences. Send transactional and targeted push notifications to Android, iOS, and Web. Fetch and manage App Inbox cards for users. Send transactional alerts across SMS, Email, and Push channels. Start, update, and end iOS Live Activities via broadcast. Fetch and manage personalized experiences for users. View and retrieve archived messages. *** ## Data Centers MoEngage maintains multiple data centers. You are assigned to a specific data center when you sign up. You can identify your data center from your dashboard URL. | Data Center | Dashboard URL | REST API Host | | ----------- | ------------------------------------ | ------------------------------ | | DC-01 | `https://dashboard-01.moengage.com` | `https://api-01.moengage.com` | | DC-02 | `https://dashboard-02.moengage.com` | `https://api-02.moengage.com` | | DC-03 | `https://dashboard-03.moengage.com` | `https://api-03.moengage.com` | | DC-04 | `https://dashboard-04.moengage.com` | `https://api-04.moengage.com` | | DC-05 | `https://dashboard-05.moengage.com` | `https://api-05.moengage.com` | | DC-06 | `https://dashboard-06.moengage.com` | `https://api-06.moengage.com` | | DC-101 | `https://dashboard-101.moengage.com` | `https://api-101.moengage.com` | ### Choosing a Data Center If you have data privacy requirements to store user data in a specific geographical region: * **US region**: Sign up with DC-01 or DC-04 * **EU region**: Sign up with DC-02 * **India region**: Sign up with DC-03 * **Singapore region**: Sign up with DC-05 * **Indonesia region**: Sign up with DC-06 After data is captured in a workspace, it cannot be migrated to a different data center. Always use the REST API endpoint matching your registered data center. *** ## Base URL All API requests are made to: ```text theme={null} https://api-{dc}.moengage.com ``` Replace `{dc}` with your data center number (e.g., `01`, `02`, `03`). You can identify your data center from your Dashboard URL. Each API may have additional path segments (e.g., `/v1`, `/core-services/v1`). Refer to the specific API documentation for the complete endpoint path. *** ## Authentication All MoEngage API requests require Basic Authentication. To authenticate, you must include a Base64-encoded string of your credentials in the Authorization header of every request. Basic Authentication sends a Base64-encoded string containing your username and password with every API request. It encodes a 'username:password' string in Base64 and appends the encoded string with 'Basic '. This string is included in the authorization header as shown below: `{"Authorization: Basic Base64_ENCODED_WORKSPACEID_APIKEY=="}` ### Required Headers ```http theme={null} Authorization: Basic {base64_encoded_credentials} MOE-APPKEY: {your_workspace_id} Content-Type: application/json ``` ### Generating Credentials The `Authorization` header value is a Base64 encoding of `workspace_id:api_key`. ```bash theme={null} # Example: Encoding credentials echo -n "YOUR_WORKSPACE_ID:YOUR_API_KEY" | base64 ``` ### Getting Your Credentials 1. Log in to the [MoEngage dashboard](https://dashboard.moengage.com). 2. Navigate to **Settings** > **Account** > **APIs**. api-dashboard 3. Copy your **Workspace ID** and the relevant **API Key**. You can perform authentication using a client like Postman as follows: Authorization ### API Keys by Feature Different APIs require different API keys from your dashboard: | API | API Key Location (Settings → Account → APIs) | | --------------------- | -------------------------------------------------------------------------- | | Data | Data | | Push | Push | | Inform | Inform | | Campaigns and Catalog | Campaign report/Business events/Custom templates/Catalog API/Inform Report | | Personalize | Personalize | ## Rate Limits Rate limits vary by API. Headers are included in responses to help you manage usage. | API | Rate Limit | | ---------------------------- | ------------------------------------------------------ | | **Campaigns API** | 5 requests/min, 25 requests/hour, 100 requests/day | | **Catalog API** | 100 requests/min or 1,000 requests/hour | | **Campaign Stats API** | 100 requests/min/workspace | | **Custom Segments (Filter)** | 50 requests/min, 200 requests/hour, 1,000 requests/day | | **Custom Segments (File)** | 10 operations/hour, 100 operations/day | ### Rate Limit Response Headers ```http theme={null} x-ratelimit-limit: 100 x-ratelimit-remaining: 95 x-ratelimit-reset: 1699574400 ``` ### Payload Size Limits | API | Max Payload Size | | ---------------------- | ---------------- | | Catalog API | 5 MB | | Recommendations API | 1 MB | | Bulk Import API | 100 KB | | Custom Segments (File) | 150 MB per file | *** ## Error Handling All APIs return consistent error responses. ### Standard Error Format ```json wrap theme={null} { "status": "fail", "error": { "message": "The request parameters are invalid", "type": "Bad Request", "request_id": "abc123xyz" } } ``` ### HTTP Status Codes | Code | Description | | ----- | ---------------------------------- | | `200` | Success | | `201` | Created | | `202` | Accepted (async processing) | | `400` | Bad Request - Invalid parameters | | `401` | Unauthorized - Invalid credentials | | `403` | Forbidden - Access denied | | `404` | Not Found - Resource doesn't exist | | `409` | Conflict - Duplicate resource | | `413` | Payload Too Large | | `429` | Rate Limit Exceeded | | `500` | Internal Server Error | *** ## Key Endpoints Reference ### Data | Method | Endpoint | Description | | ------ | ------------------------------------ | ------------------------ | | `POST` | `/customer/{Workspace_ID}` | Create or update user | | `POST` | `/customers/export` | Get user details | | `POST` | `/customer/merge` | Merge two users | | `POST` | `/customer/delete` | Delete users in bulk | | `POST` | `/event/{Workspace_ID}` | Track user events | | `POST` | `/transition/{Workspace_ID}` | Bulk import | | `POST` | `/device/{app_id}` | Create or update device | | `POST` | `/devices/manage` | Manage devices | | `POST` | `/fileimports/trigger/{schedule_id}` | Trigger file import | | `POST` | `/fileimports/import/status` | Get import status | | `GET` | `/installInfo` | Get install info | | `POST` | `/integrations/authentication` | Validate authentication | | `POST` | `/opengdpr_requests/{appId}` | Create GDPR/CCPA request | ### Business Events | Method | Endpoint | Description | | ------ | ------------------------- | ---------------------- | | `POST` | `/business_event` | Create business event | | `POST` | `/business_event/trigger` | Trigger business event | | `POST` | `/business_event/search` | Search business events | ### Content #### Templates | Method | Endpoint | Description | | ------ | -------------------------------- | ------------------------ | | `POST` | `/custom-templates/inapp` | Create In-App template | | `PUT` | `/custom-templates/inapp` | Update In-App template | | `POST` | `/custom-templates/inapp/search` | Search In-App templates | | `POST` | `/custom-templates/osm` | Create OSM template | | `PUT` | `/custom-templates/osm` | Update OSM template | | `POST` | `/custom-templates/osm/search` | Search OSM templates | | `POST` | `/custom-templates/sms` | Create SMS template | | `PUT` | `/custom-templates/sms` | Update SMS template | | `POST` | `/custom-templates/sms/search` | Search SMS templates | | `POST` | `/email-templates` | Create Email template | | `GET` | `/email-templates` | Get all Email templates | | `GET` | `/email-templates/{id}` | Get Email template by ID | | `PUT` | `/email-templates/{id}` | Update Email template | | `POST` | `/custom-templates/email` | Create Email template V2 | | `PUT` | `/custom-templates/email` | Update Email template V2 | | `POST` | `/custom-templates/push` | Create Push template | | `PUT` | `/custom-templates/push` | Update Push template | | `POST` | `/custom-templates/push/search` | Search Push templates | #### Content Blocks | Method | Endpoint | Description | | ------ | ---------------------------- | ------------------------- | | `POST` | `/content-blocks` | Create content block | | `PUT` | `/content-blocks` | Update content block | | `POST` | `/content-blocks/get-by-ids` | Get content blocks by IDs | | `POST` | `/content-blocks/search` | Search content blocks | #### Recommendations | Method | Endpoint | Description | | ------ | --------------------------------------------- | ------------------------ | | `GET` | `/recommendations/{recommendations_id}` | Get recommendations | | `POST` | `/recommendations/{recommendations_id}/items` | Get recommendation items | #### Coupons | Method | Endpoint | Description | | -------- | ------------------------------------------------------ | -------------------- | | `POST` | `/coupon-list` | Create coupon list | | `GET` | `/coupon-list` | List coupon lists | | `GET` | `/coupon-list/{coupon_list_id}` | Get coupon list | | `PATCH` | `/coupon-list/{coupon_list_id}` | Update coupon list | | `PUT` | `/coupon-list/{coupon_list_id}/activate` | Activate coupon list | | `PUT` | `/coupon-list/{coupon_list_id}/archive` | Archive coupon list | | `POST` | `/coupon-list/{coupon_list_id}/files` | Upload coupon file | | `GET` | `/coupon-list/{coupon_list_id}/files` | List coupon files | | `GET` | `/coupon-list/{coupon_list_id}/files/{coupon_file_id}` | Get coupon file | | `DELETE` | `/coupon-list/{coupon_list_id}/files/{coupon_file_id}` | Delete coupon file | | `POST` | `/coupon-list/{coupon_list_id}/usage-report` | Get usage report | #### Catalog | Method | Endpoint | Description | | ------- | ----------------------------------------- | ---------------------- | | `POST` | `/catalog` | Create catalog | | `PATCH` | `/catalog/{catalog_id}/attributes` | Add catalog attributes | | `POST` | `/catalog/{catalog_id}/items` | Ingest catalog items | | `POST` | `/catalog/{catalog_id}/items/search` | Search catalog items | | `PATCH` | `/catalog/{catalog_id}/items` | Update catalog items | | `POST` | `/catalog/{catalog_id}/items/bulk-delete` | Delete catalog items | ### Campaigns | Method | Endpoint | Description | | ------- | ------------------------------------------------ | ------------------------ | | `POST` | `/campaigns` | Create campaign | | `PATCH` | `/campaigns/{campaign_id}` | Update campaign | | `POST` | `/campaigns/search` | Search campaigns | | `POST` | `/campaigns/test` | Test campaign | | `POST` | `/personalization/preview` | Preview personalization | | `POST` | `/campaigns/meta` | Get campaign metadata | | `POST` | `/campaigns/status` | Get campaign status | | `POST` | `/campaigns/{parent_campaign_id}/executions` | Get campaign executions | | `POST` | `/core-services/v1/campaign-stats` | Get campaign stats | | `GET` | `/campaign_reports/rest_api/{APP_ID}/{FILENAME}` | Download campaign report | ### Segments | Method | Endpoint | Description | | ------- | ----------------------------------------------- | ------------------------- | | `POST` | `/v2/custom-segments/file-segment` | Create file segment | | `PUT` | `/v2/custom-segments/file-segment/add-users` | Add users to segment | | `PUT` | `/v2/custom-segments/file-segment/remove-users` | Remove users from segment | | `PUT` | `/v2/custom-segments/file-segment/replace` | Replace segment users | | `GET` | `/v3/custom-segments` | List filter segments | | `POST` | `/v3/custom-segments` | Create filter segment | | `GET` | `/v3/custom-segments/{id}` | Get segment by ID | | `PATCH` | `/v3/custom-segments/{id}` | Update filter segment | | `POST` | `/v1/integrations/cohortsync` | Sync cohort audience | | `PATCH` | `/v2/custom-segments/archive` | Archive segment | | `PATCH` | `/v2/custom-segments/unarchive` | Unarchive segment | ### Subscriptions | Method | Endpoint | Description | | ------ | ------------------------------------------ | ------------------------------- | | `POST` | `/emails/v1.0/bulk-resubscribe` | Bulk resubscribe emails | | `PUT` | `/v1.0/opt-in-management/user-preferences` | Update opt-in preferences | | `GET` | `/category-subscription/user-preferences` | Get subscription preferences | | `PUT` | `/category-subscription/user-preferences` | Update subscription preferences | | `POST` | `/category-subscription/user-preferences` | Create subscription preferences | ### Push | Method | Endpoint | Description | | ------ | ----------------------- | ---------------------- | | `POST` | `/transaction/sendpush` | Send push notification | ### Cards | Method | Endpoint | Description | | -------- | --------------- | ------------ | | `POST` | `/cards/fetch` | Fetch cards | | `DELETE` | `/cards/delete` | Delete cards | ### Inform | Method | Endpoint | Description | | ------ | -------------- | ----------------------------------------- | | `POST` | `/alerts/send` | Send transactional alert (SMS/Email/Push) | ### Live Activities | Method | Endpoint | Description | | ------ | --------------------------------- | -------------------- | | `POST` | `/live-activity/broadcast/start` | Start Live Activity | | `POST` | `/live-activity/broadcast/update` | Update Live Activity | | `POST` | `/live-activity/broadcast/end` | End Live Activity | ### Personalize | Method | Endpoint | Description | | ------ | ----------------------- | ----------------------- | | `POST` | `/experiences/fetch` | Fetch experiences | | `GET` | `/experiences/metadata` | Get experience metadata | | `POST` | `/experiences/events` | Track experience events | ### Message Archival | Method | Endpoint | Description | | ------ | ---------------- | ---------------------- | | `POST` | `/archival/view` | View archived messages | *** ## Support Need help with the API? * **Help Center**: [help.moengage.com](https://help.moengage.com/hc/en-us) * **Support**: Contact your Customer Success Manager or reach out via the dashboard. # Add Items Source: https://moengage.com/docs/api/items/add-items /api/catalog/catalog.yaml post /catalog/{catalog_id}/items This API ingests items into an existing catalog as long as the attributes provided during ingestion match the attributes provided during catalog creation. #### Rate Limit * Request limit: You can ingest 100 items per minute OR 1000 items per hour. You can ingest up to 50 items per request. * Payload size limit: 5 MB only when Content-Length header is provided. # Delete Items Source: https://moengage.com/docs/api/items/delete-items /api/catalog/catalog.yaml post /catalog/{catalog_id}/items/bulk-delete This API deletes existing items in a given catalog. #### Rate Limit * Request limit: You can delete 100 items per minute OR 1000 items per hour. You can delete up to 50 items per request. * Payload size limit: 5 MB only when Content-Length header is provided. # Get Items Source: https://moengage.com/docs/api/items/get-items /api/catalog/catalog.yaml post /catalog/{catalog_id}/items/search This API retrieves item attribute details for catalog items using their unique item IDs. The attributes can include the title, price, category, link, image_link, and the respective creation date. #### Rate Limit * Request limit: You can get 100 item attribute details per minute OR 1000 item attribute details per hour. You can request up to 50 items per request. * Payload size limit: 5 MB only when the Content-Length header is provided. The limit is a COMBINED limit across all Catalog APIs for a specific user. # Update Items Source: https://moengage.com/docs/api/items/update-items /api/catalog/catalog.yaml patch /catalog/{catalog_id}/items This API updates items with new attribute values. Attributes must adhere to the data type defined. #### Rate Limit * Request limit: You can update 100 items per minute OR 1000 items per hour. You can update up to 50 items per request. * Payload size limit: 5 MB only when Content-Length header is provided. # End Broadcast Live Activity Source: https://moengage.com/docs/api/live-activities/end-broadcast-live-activity /api/live-activities/live-activities.yaml post /live-activity/broadcast/end This API terminates a broadcast Live Activity across all subscribed devices simultaneously, with options for a final state update or immediate dismissal. #### Rate Limit The rate limit for this endpoint is 500 requests per minute per workspace and 5 requests per minute per live activity ID. # Live Activities Overview Source: https://moengage.com/docs/api/live-activities/live-activities-overview Initiate, update, and terminate shared real-time activities for iOS users. The MoEngage Broadcast Live Activities API enables brands to manage shared, real-time experiences for large audiences on iOS. This is ideal for live sporting events, election tracking, or breaking news where multiple users need to see the same real-time updates on their lock screens or Dynamic Island. Live Activities can only be managed for push campaigns created with the **BROADCAST\_LIVE\_ACTIVITY** delivery type via the [Create Push Campaigns API](https://developers.moengage.com/hc/en-us/articles/38466364097044-Create-Push-Campaigns). These campaigns cannot be created through the MoEngage UI. ## Endpoints The Broadcast Live Activities API consists of the following endpoints: * [**Start Broadcast Live Activity**](/api/live-activities/start-broadcast-live-activity): Initiates the shared activity and sends the initial content to the target audience. * [**Update Broadcast Live Activity**](/api/live-activities/update-broadcast-live-activity): Pushes unified updates (e.g., score changes) to all subscribed devices. * [**End Broadcast Live Activity**](/api/live-activities/end-broadcast-live-activity): Terminates the activity session across all devices. ## FAQs No. Live Activities are a native iOS feature. This API specifically targets iOS devices supporting the ActivityKit framework. The `broadcast_live_activity_id` refers to the overarching campaign ID created via the Push API. The `instance_id` is an optional field you can provide to track a specific session or prevent duplicate requests for the same event. Content is updated via the `content_state` JSON object. The keys within this object must match the `ContentState` struct defined in your iOS application code. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [View in Postman](https://www.postman.com/moengage-dev/api-docs/folder/etd05kq/start-live-activity) # Start Broadcast Live Activity Source: https://moengage.com/docs/api/live-activities/start-broadcast-live-activity /api/live-activities/live-activities.yaml post /live-activity/broadcast/start This API initiates a shared, real-time activity for a large audience, such as a live sporting match or real-time election result tracking. You can start live activities for only push campaigns created with the BROADCAST\_LIVE\_ACTIVITY delivery type using the [Create Push Campaigns API](https://www.moengage.com/docs/api/create-campaigns/create-campaign), not campaigns created through the MoEngage UI. #### Rate Limit The rate limit for this endpoint is 5 requests per minute per workspace. # Update Broadcast Live Activity Source: https://moengage.com/docs/api/live-activities/update-broadcast-live-activity /api/live-activities/live-activities.yaml post /live-activity/broadcast/update This API pushes a single, unified update to all subscribed Live Activities, such as an updated game score or a new development in a breaking news story. #### Rate Limit The rate limit for this endpoint is 500 requests per minute per workspace and 5 requests per minute per live activity ID. # Archive Segment Source: https://moengage.com/docs/api/manage-segments/archive-segment /api/custom-segments/custom-segments.yaml patch /v2/custom-segments/archive This API archives an existing segment (File or Filter). Archiving and unarchiving through APIs makes it easy to retrieve and reuse segments whenever required for purposes such as A/B testing, maintaining regulatory compliance, and improving system performance. You can access the archived segments and utilize them to analyze and market campaigns without the need to recreate them from scratch. Archived segments will not be shown beyond 180 days. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # Unarchive Segment Source: https://moengage.com/docs/api/manage-segments/unarchive-segment /api/custom-segments/custom-segments.yaml patch /v2/custom-segments/unarchive This API unarchives an existing segment, making it active again. This API endpoint does not currently support Team-level scoping. All segments generated using this call will be assigned to the Default Team automatically. # Message Archival Overview Source: https://moengage.com/docs/api/message-archival/messaage-archival-overview Retrieve and view archived copies of sent communication across Push, Email, and SMS. The MoEngage Message Archival API provides a way to store and access historical records of communications sent to your customers. By utilizing this API, you can retrieve the exact content—including titles, messages, and media URLs—that was delivered to a specific user at a specific time. This is particularly useful for customer support teams who need to verify what a customer received, or for compliance audits where a historical record of messaging is required. ## Endpoint The Message Archival API consists of the following endpoint: * [View Archived Message](/api/message-archival/view-archived-message): Retrieves the full content and metadata of a specific message sent to a user via Push, Email, or SMS. ## FAQs To retrieve a message, you must provide the `user_id`, the `campaign_id`, and the `sent_epoch_time` (Unix timestamp) of the communication. For event-triggered campaigns, passing the `event_id` is also required. * **message\_content**: Contains the actual personalized content sent to the user. * **backup\_content**: Contains the original template or default content used if personalization failed or was not applied. # Message archival overview Source: https://moengage.com/docs/api/message-archival/message-archival-overview # View Archived Message Source: https://moengage.com/docs/api/message-archival/view-archived-message /api/message-archival/message-archival.yaml post /archival/view You can use this API to store any communication sent to customers for later access. #### Rate Limit The rate limit for this endpoint is **1000 RPM**. # Update User Email Opt-in Preferences Source: https://moengage.com/docs/api/opt-in-management/update-user-email-opt-in-preferences /api/email-subscription/email-subscription.yaml put /v1.0/opt-in-management/user-preferences This API updates a user's overall email opt-in status and/or category-level subscription preferences within MoEngage. This API is typically used after a user submits the second confirmation through MoEngage consent-seeking emails (Double Opt-in). #### Rate Limit The rate limit is **1000 RPM** (requests per minute) and **360K** requests per day. If you use PII Tokenization for your emails, ensure you pass the user ID when calling the Email Opt-in Management API. MoEngage uses this user ID to locate the user and update their opt-in status. Passing the email ID is ineffective in this case, as MoEngage does not store it. If you use PII Encryption to send emails, ensure you pass either the user ID or the decrypted email ID. MoEngage uses this information to locate the associated user and update their opt-in status, or to update the opt-in status of all users having that email ID. # Create OSM Template Source: https://moengage.com/docs/api/osm-templates/create-osm-template /api/osm-templates/osm-templates.yaml post /custom-templates/osm This API creates a new On-Site Messaging (OSM) template. You can use this API to upload templates created outside the MoEngage ecosystem to MoEngage and use them for campaign creation. API templates cannot be used in the Drag and Drop Editor in the MoEngage Dashboard. They are only supported for the Custom HTML Editor. #### Rate Limit The rate limit is 100 RPM. You can upload a maximum of 100 templates per minute. # OSM Templates Overview Source: https://moengage.com/docs/api/osm-templates/osm-templates-overview Create, search, and update On-Site Messaging (OSM) templates. The MoEngage On-Site Messaging (OSM) Templates API allows you to manage your web and app-site messaging templates. You can use this API to upload custom HTML templates created outside the MoEngage ecosystem, making them available for your OSM campaigns. This API supports multiple template formats including **Banners**, **Pop-ups**, and **Nudges**. Note that templates created via this API are supported within the **Custom HTML Editor** in the MoEngage Dashboard and cannot be used with the Drag and Drop Editor. ## Endpoints The OSM Templates API is a collection of the following endpoints: * [Create OSM Template](/api/osm-templates/create-osm-template): Creates a new OSM template with an HTML payload. * [Update OSM Template](/api/osm-templates/update-osm-template): Updates an existing OSM template and handles campaign versioning. * [Search OSM Templates](/api/osm-templates/search-osm-templates): Retrieves templates based on filters like template type, source, or creator. ## FAQs The API currently supports the creation and management of **BANNER**, **POP\_UP**, and **NUDGE** template types. All payloads must be in HTML format. No. Templates uploaded via the API are only compatible with the **Custom HTML Editor** in the MoEngage Dashboard. When updating a template, you can set the `update_campaigns` flag. * **True**: Automatically updates all running campaigns to the new template version. * **False**: Creates a new version without affecting existing campaigns. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/28342601-e2d062c4-11b3-45cc-9249-a58d939c3497?action=share\&source=copy-link\&creator=28342601) # Search OSM Templates Source: https://moengage.com/docs/api/osm-templates/search-osm-templates /api/osm-templates/osm-templates.yaml post /custom-templates/osm/search This API searches the OSM templates created in your MoEngage account. **Mandatory Pagination** We are introducing mandatory pagination, effective **November 15, 2025**. All calls to this API must include the following two parameters: * `page`: The page number of the results you wish to fetch. * `entries`: The number of templates to return per page, with a maximum value of *15*. Please update all integrations to include these parameters. API requests submitted without them after the effective date will result in an error and fail to execute. * If the request body is passed empty, then all templates will be returned. * The `preview_image` field in the response will be generated by MoEngage for the HTML template payload. #### Rate Limit The rate limit is 100 RPM. # Update OSM Template Source: https://moengage.com/docs/api/osm-templates/update-osm-template /api/osm-templates/osm-templates.yaml put /custom-templates/osm This API updates an OSM template as per your requirements. #### Rate Limit The rate limit is 100 RPM. # Personalize Overview Source: https://moengage.com/docs/api/personalize-experience/personalize-overview Fetch personalized content and report experience events from your server-side codebase. Personalize APIs constitute a set of endpoints that allow you to deliver tailored user experiences directly from your platform's code. Unlike client-side personalization, these server-side APIs must be invoked within your rendering pipeline to receive relevant data. Once your platform receives the personalized payload, you can use it to dynamically render content—such as banners, product recommendations, or pricing—specifically for the requesting user. MoEngage automatically evaluates targeting rules, in-session attributes, and segments to return the correct variation. ## Endpoints The Personalize API suite is categorized into experience management and event reporting: * [Fetch Experience](/api/experiences/fetch-experience): Evaluates targeting rules and returns the personalized payload (variations) for a user. * [Fetch Experience Metadata](/api/experiences/fetch-experience-metadata): Retrieves a list of all currently Active, Scheduled, or Paused experiences. * [Track Experience Events](/api/events/report-experience-events): Tracks impressions (shown) and user interactions (clicked) for accurate campaign reporting. ## Reporting Experience Events You can report impressions and clicks for server-side experiences using either the API or a MoEngage SDK, depending on your platform: | Method | Platforms | Notes | | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Track Experience Events API](/api/events/track-experience-events) | All (Web, Mobile, TV, etc.) | **Recommended.** Works across all platforms and keeps tracking logic consistent with server-side content delivery. The API request to report clicks remains the same as the one to report impressions. The only change is to the value of the **action** field (*MOE\_PERSONALIZATION\_MESSAGE\_SHOWN* or *MOE\_PERSONALIZATION\_MESSAGE\_CLICKED*). | | [MoEngage Web SDK](https://developers.moengage.com/hc/en-us/articles/39084350090772-Personalize-API-Experience-events-tracking#h_01JXWHX5488QT9XMEN0R5WPX6P) | Web | Use the Personalize SDK to report experience events from a website. | | [MoEngage Android SDK](https://developers.moengage.com/hc/en-us/articles/38474488247444-Personalize-Experience-Events-Tracking#h_01JXWHX5488QT9XMEN0R5WPX6P) | Android | Report experience events natively from an Android app. | | [MoEngage iOS SDK](https://developers.moengage.com/hc/en-us/articles/38532362954004-Personalize-Experience-Events-tracking#h_01JY0XF2DW9VKRF3S7G5FNR4XR) | iOS | Report experience events natively from an iOS app. | ## FAQs ### Experience Management Yes. By passing multiple values in the `experience_key` array (e.g., `["hero-banner", "sidebar-promo"]`), you can receive personalized content for multiple sections of your page in one request. The API primarily uses the `customer_id`. If that is inaccurate or missing, you can use `user_identifiers` (like email or mobile number) as a fallback, provided **Identity Resolution** is enabled in your MoEngage workspace. ### Security and Events Only regenerate your API Secret in the event of a security breach. Note that once a new secret is saved, all existing integrations using the old key will immediately stop working. For server-side personalization, using the **Report Experience Events API** is recommended for all platforms (Web, Mobile, TV) as it keeps the tracking logic consistent with the content delivery logic. You can use the `b_id` field within the events payload to uniquely identify which element was clicked (e.g., "Add to Cart" vs "Wishlist") within the same personalized experience. # Push Templates Overview Source: https://moengage.com/docs/api/push-templates/push-templates-overview Create, update, and search for push notification templates. The MoEngage Push Templates API allows you to create, update, and search for push notification templates for Android and iOS platforms. Use these endpoints to manage your template library efficiently and integrate it into your automated workflows. If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. ## Endpoints The Push Templates API is a collection of the following endpoints: * [Create Push Template](/api/templates/create-push-template): Creates a push template. * [Update Push Template](/api/templates/update-push-template): Updates a push template specified by its Template ID. * [Search for Push Templates](/api/templates/search-for-push-templates): Fetches a push template using its Template ID or other filters like template name, platform, and so on. ## FAQs Yes, you can send only the iOS payload if you want to create a template for iOS. Audio and video: All types of video and audio file formats supported by standard FCM/APNS platforms are supported. **Images:** The following formats are supported: "image/png", "image/jpeg", "image/jpg", "image/gif". Yes, you can create multiple templates with the same name, provided they have different versions. ## Postman Collections We have made it easy for you to test the APIs. Click here to view the [Postman collection](https://www.postman.com/moengage-dev/api-docs/folder/3182294-9043f92c-dd0c-4ad7-b619-df7d4b7c4d87). # Push Overview Source: https://moengage.com/docs/api/push/push-overview Create campaigns and send personalized push notifications to individual users or segments across Android, iOS, and Web. The MoEngage Push API allows you to trigger push notifications. It is designed for high-throughput transactional and marketing use cases, supporting complex targeting logic and deep personalization for every recipient. Use this API to: * **Target Segments:** Send notifications to all users or specific pre-defined segments. * **Target Individuals:** Reach a single user using unique attributes like Email, Mobile Number, or Unique ID. * **Personalize at Scale:** Use Jinja templating to dynamicially inject user-specific data into the notification payload. ## Endpoint The Push API consists of the following endpoint: * [Send Push Notification](/api/transactional/send-push-notification): Creates and sends a push notification campaign. ## FAQs No, the MoEngage Push API currently does not support silent (data-only) notifications. Yes, the basic template supports standard HTML tags for text formatting on supported platforms. You can provide a `fallback` object within the payload. If the personalization logic fails (e.g., a missing user attribute), the system will automatically send the fallback content instead. In the `targetUserAttributes` object, set the `attribute` field to `PUSH_ID` and provide the device token as the `attributeValue`. ## Postman Collection We have made it easy for you to test the APIs. Click [here](https://www.postman.com/moengage-dev/api-docs/collection/acmujor/moengage-transaction-push-api?action=share\&source=copy-link\&creator=5883765) to view the collection in Postman. # Fetch Recommendation Details Source: https://moengage.com/docs/api/recommendations/fetch-recommendation-details /api/recommendations/recommendations.yaml get /recommendations/{recommendations_id} This API retrieves the metadata associated with a specific recommendation setup using its unique ID. The metadata can include the recommendation name, model type, status, creation and update time, and so on. #### Rate Limit You can fetch 1,000 recommendations per minute. # Fetch Recommendation Results Source: https://moengage.com/docs/api/recommendations/fetch-recommendation-results /api/recommendations/recommendations.yaml post /recommendations/{recommendations_id}/items This API fetches/retrieves the metadata results of any recommendations for a user based on their user ID and item ID. #### Rate Limit You can fetch 10,000 recommendations per minute. # Recommendations Overview Source: https://moengage.com/docs/api/recommendations/recommendations-overview Fetch recommendation metadata and retrieve personalized item results. The MoEngage Recommendation API allows you to interact with your recommendation engines. You can retrieve the configuration metadata of a specific recommendation setup or fetch the actual recommended items for a specific user based on various models like "Similar Items," "Frequently Bought Together," or "Trending." If this API is not enabled for your account, contact your MoEngage Customer Success Manager (CSM) or the Support team to request enablement. ## Endpoints The Recommendation API is a collection of the following endpoints: * [Fetch Recommendation Metadata](/api/recommendations/fetch-recommendation-metadata): Fetches configuration details, status, and logic. * [Fetch Recommendation Results](/api/recommendations/fetch-recommendation-results): Fetches personalized items for a user. ## FAQs ### General Recommendation Questions The `recommendations_id` is a unique identifier generated when you create a recommendation in the MoEngage Recommendation module. You can find this ID on the individual recommendation's overview page in the MoEngage Dashboard. By default, the API returns all attributes associated with an item in the catalog. For catalogs with many attributes, this can significantly increase response size and latency. Specifying only the fields you need (e.g., `["title", "price", "image_link"]`) improves performance. ### Fetch Results The `item_id` acts as an anchor for collaborative filtering models. It is mandatory when the `RECOMMENDATION-TYPE` is set to `similar_item`, `frequently_viewed_together`, or `frequently_bought_together`. The API requires a valid `user_id`. If the user is unknown or hasn't had any interactions recorded, the recommendation engine may return default items (like trending items) or an empty list depending on your "fallback" settings in the dashboard. The API will return a `413 Request Entity Too Large` error. This usually happens if the `include_fields` list is excessively long or if a very high number of items are requested (if applicable). ## Postman Collections Test the Recommendation APIs immediately using our Postman collection. [View Postman Collection](https://www.postman.com/moengage-dev/api-docs/collection/35sr4cv/moengage-recommendation-public-api) # Generate Usage Report Source: https://moengage.com/docs/api/reports/generate-usage-report /api/coupons/coupons.yaml post /coupon-list/{coupon_list_id}/usage-report This API produces a detailed usage report for a specific coupon list, providing details on which user received which coupon from which locale or variation of which campaign at what time. After it is generated, this report is delivered directly to the requested email addresses. Using this API, you can conduct a comprehensive analysis of critical data and coupon usage trends efficiently. #### Rate Limit You can generate: * 5 usage reports of coupon list per minute or * 50 usage reports of coupon list per day # Bulk Resubscribe Users Source: https://moengage.com/docs/api/resubscribe/bulk-resubscribe-users /api/email-subscription/email-subscription.yaml post /emails/v1.0/bulk-resubscribe This API resubscribes users who have previously unsubscribed on the MoEngage platform and an external email vendor platform simultaneously. This API resets the unsubscribe flag to “false” for users on MoEngage and makes a call to an External Service Provider (ESP) like SendGrid to remove the email addresses (associated with the unsubscribed users) from their suppression list. #### Supported ESPs The Resubscription API currently supports only **SendGrid**. #### Rate Limit The rate limit is **10 RPM** (requests per minute). The allowed volume is **14.4K** requests per day, with a maximum payload size of **100** recipient email addresses per request. # Create SMS Template Source: https://moengage.com/docs/api/sms-templates/create-sms-template /api/sms-templates/sms-templates.yaml post /custom-templates/sms This API creates an SMS template in MoEngage. It helps you upload templates created outside the MoEngage ecosystem to MoEngage and use them for campaign creation. #### Rate Limit The rate limit is **100 RPM**. You can upload a maximum of **100 templates per channel**. # Search SMS Templates Source: https://moengage.com/docs/api/sms-templates/search-sms-templates /api/sms-templates/sms-templates.yaml post /custom-templates/sms/search This API searches and retrieves a list of SMS templates, created in your MoEngage account, based on specified filter criteria. **Mandatory Pagination Update** We are introducing mandatory pagination, effective **November 15, 2025**, all calls to this API must include the following two parameters: * `page`: The page number of the results you wish to fetch. * `entries`: The number of templates to return per page, with a maximum value of **15**. Please update all integrations to include these parameters. API requests submitted without them after the effective date will result in an error and fail to execute. #### Rate Limit The rate limit is **100 RPM**. # SMS Templates Overview Source: https://moengage.com/docs/api/sms-templates/sms-templates-overview Use the MoEngage SMS Templates API to create, search, and update reusable SMS templates for campaigns. The MoEngage SMS Template API allows marketers define, reuse, update, and manage SMS templates created outside the MoEngage ecosystem effortlessly. You can create multiple versions of the same template and mark whether they can be used in the campaigns that are active currently. Users can create templates using the Create SMS Template API and update them using the Update SMS Template API or edit them in the MoEngage dashboard (provided they have the specific editing permissions for the templates allowed for their role).  ## Endpoints The SMS Template API is a collection of the following endpoints: * [Create SMS Template](/api/sms-templates/create-sms-template): Creates an SMS template. * [Update SMS Template](/api/sms-templates/update-sms-template): Updates an SMS template specified by its Template ID. * [Search SMS Template](/api/sms-templates/search-sms-templates): Fetches an SMS template using its Template ID or other filters like template name, template version, and so on. It can also list all the SMS templates created in MoEngage. ## FAQs ### Create SMS Template Yes, you can create multiple templates with the same name, provided they have different versions. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/n0lb9wd/moengage-custom-templates-api?action=share\&creator=3182294) # Update SMS Template Source: https://moengage.com/docs/api/sms-templates/update-sms-template /api/sms-templates/sms-templates.yaml put /custom-templates/sms This API updates an SMS template by specifying its external template ID. You can specify in the request whether the updated version of the template can be used in active campaigns. #### Rate Limit The rate limit is **100 RPM**. # Campaign Stats and Reports Overview Source: https://moengage.com/docs/api/stats-report/stats-report-overview Fetch real-time campaign performance statistics and download detailed campaign reports programmatically. The MoEngage Campaign Stats and Reports API allows you to monitor your marketing performance outside of the MoEngage dashboard. Use these endpoints to retrieve real-time platform-level statistics or generate downloadable reports for long-term analysis. ## Endpoints The Campaign Stats and Reports API is divided into two primary functional areas: * [Get Campaign Stats](/api/stats/get-campaign-stats): Retrieves real-time performance metrics (clicks, impressions, conversions) at a platform level. * [Download Campaign Report](/api/campaign-reports/download-campaign-report): Directly downloads campaign data files for specified date ranges. ## Comparison of Capabilities | Feature | Campaign Stats API | Campaign Report API | | ----------------- | -------------------------- | ------------------------- | | **Data Recency** | Real-time | Historical (Date Range) | | **Output Format** | JSON | ZIP/GZIP File | | **Batch Limit** | 10 Campaigns per call | 90 Days date range | | **Primary Use** | Live Monitoring/Dashboards | Deep-dive Analysis/Audits | ## FAQs ### Campaign Statistics You can pass up to **10 campaign IDs** in the `campaign_ids` array per API call. If you need data for more campaigns, utilize the `offset` and `limit` parameters to paginate through your results. The `metric_type` parameter allows you to toggle your view. **TOTAL** counts every occurrence (e.g., three clicks by one user), while **UNIQUE** counts the number of distinct users who performed the action. Yes. The response object is nested by Platform > Locale > Variation, allowing you to see granular performance for A/B tests and localized content. If only the start date is passed without the end date, the API will return an error response. Both the start and end dates are required to retrieve the desired response. When providing the start and end dates without any campaign ID, the API will return the stats for both the parent and child campaigns. The stats will be available for the specified time period. To identify the stats belonging to the parent campaign in the API response, you can use the "Campaign Details and Reachability" API. This API should be called with all the campaign IDs included in the request. The parent campaign ID field will not be available for the parent campaign, allowing you to distinguish it from the child campaigns. Campaign Details and Reachability APIs will allow you to relate child campaigns to their parent campaigns. ### Campaign Reports This typically happens if the `FILENAME` provided is incorrect, the report was created more than 7 days ago (expired), or the `APP_ID` in the path does not match your credentials. Yes, the Report API supports both one-time and periodic campaigns. Ensure the filename matches the specific instance you wish to download. Verify that your concatenation uses the pipe character (`|`) exactly as shown: `APPID|FILENAME|SECRETKEY`. Ensure the resulting string is encoded in UTF-8 before hashing with SHA256. Campaigns might not be available to run on the selected date to fetch the report, which could result in an error message. The reports generated will expire in 7 days from the date of creation. You can generate reports for up to 90 days. ## Postman Collections Test your integration and verify your signature logic using our Postman collection. [View Postman Collection](https://www.postman.com/moengage-dev/api-docs/collection/s8t1ta0/moengage-campaign-stats-api) → # Get Campaign Stats Source: https://moengage.com/docs/api/stats/get-campaign-stats /api/stats-report/stats-report.yaml post /core-services/v1/campaign-stats This API fetches data at the platform level and provides data for all types of campaigns. #### Rate Limit This API provides all version stats, and the call rate is limited to **100 API calls per minute** per workspace. # Subscription Categories Overview Source: https://moengage.com/docs/api/subscription-categories/subscription-categories-overview Fetch and update email subscription preferences on your MoEngage dashboard. The MoEngage Subscription Categories API allows you to manage and synchronize user communication preferences across your systems and MoEngage. These endpoints support fetching individual settings, updating preferences via campaign interactions, and performing high-volume bulk updates. For more information on Subscription categories, refer to [Subscription Categories](https://help.moengage.com/hc/en-us/articles/11053939178004).  ## Endpoints The Subscription Categories API consists of the following endpoints: * [Get Subscription Preferences](/api/subscription-preferences/get-subscription-preferences): Fetches the subscription category preferences information for a specific user. * [Update Subscription Preferences](/api/subscription-preferences/update-subscription-preferences): Updates the subscription category preferences information for a specific user who navigates to the custom landing page from the email notification sent to them and updates their preferences. * [Bulk Update Subscription Preferences](https://moengage.mintlify.app/api/subscription-preferences/bulk-update-subscription-preferences): Updates subscription category preferences in bulk. Use this API for updating the user preferences to MoEngage in large volumes. ## FAQs ### Get Subscription Preferences The user\_id (MoEngage ID) and the cid (Campaign ID) fields should be fetched from the landing page URL. For example, if the link to the custom landing page was `https://www.abc.com/managepreference`, when the user clicks the same from the email, the link will be as below: ```json theme={null} https://www.abc.com/managepreference?user_id=7XvJW2dj3iS.rYAt4pg5ASBQtaqAMFDw9e89vZCXx_RFfN3eL0wBG008oI6cpncOQV6ESg&cid=5FGZGcA8FRv3Id89JCCczQjwxq6ApEyAarYDje2mzfRQ_WG7VyyFEc0w4L3MA.31a7wzR64fi7lfq8Km0AaeO4paGVul.4HxixDYnoUp21xyUjGtfvnrHSR2G1reTpYPHHU.r3Ac9vE&app_key=UY_GHXBXyaHbiYnCoNOu7eS.u5yIrrN3noTBNZX5mNSL4KN5C5PZ3zcXBKCCxl9w3m0ukw ``` Here, you can parse and find user\_id and cid * user\_id is: 7XvJW2dj3iS.rYAt4pg5ASBQtaqAMFDw9e89vZCXx\_RFfN3eL0wBG008oI6cpncOQV6ESg * cid is: 5FGZGcA8FRv3Id89JCCczQjwxq6ApEyAarYDje2mzfRQ\_WG7VyyFEc0w4L3MA.31a7wzR64fi7lfq8Km0AaeO4paGVul.4HxixDYnoUp21xyUjGtfvnrHSR2G1reTpYPHHU.r3Ac9vE and pass the same while triggering the API. ### Update Subscription Preferences The user\_id (MoEngage ID) and the cid (Campaign ID) fields should be fetched from the landing page URL. For example, if the link to the custom landing page was `https://www.abc.com/managepreference`, when the user clicks the same from the email, the link will be as below: ```json theme={null} https://www.abc.com/managepreference?user_id=7XvJW2dj3iS.rYAt4pg5ASBQtaqAMFDw9e89vZCXx_RFfN3eL0wBG008oI6cpncOQV6ESg&cid=5FGZGcA8FRv3Id89JCCczQjwxq6ApEyAarYDje2mzfRQ_WG7VyyFEc0w4L3MA.31a7wzR64fi7lfq8Km0AaeO4paGVul.4HxixDYnoUp21xyUjGtfvnrHSR2G1reTpYPHHU.r3Ac9vE&app_key=UY_GHXBXyaHbiYnCoNOu7eS.u5yIrrN3noTBNZX5mNSL4KN5C5PZ3zcXBKCCxl9w3m0ukw ``` Here, you can parse and find user\_id and cid * user\_id is: 7XvJW2dj3iS.rYAt4pg5ASBQtaqAMFDw9e89vZCXx\_RFfN3eL0wBG008oI6cpncOQV6ESg * cid is: 5FGZGcA8FRv3Id89JCCczQjwxq6ApEyAarYDje2mzfRQ\_WG7VyyFEc0w4L3MA.31a7wzR64fi7lfq8Km0AaeO4paGVul.4HxixDYnoUp21xyUjGtfvnrHSR2G1reTpYPHHU.r3Ac9vE and pass the same while triggering the API. ### Bulk Update Subscription Preferences The maximum batch size is 50. ## Postman Collection Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/30vndhm/moengage-subscription-categories-api) # Bulk Update Subscription Preferences Source: https://moengage.com/docs/api/subscription-preferences/bulk-update-subscription-preferences /api/subscription-categories/subscription-categories.yaml post /category-subscription/user-preferences This API updates subscription category preferences in bulk. You can use this API to update the user preferences to MoEngage in large volumes. #### Rate Limit The rate limit is 100 RPM and 360k per day. # Get Subscription Preferences Source: https://moengage.com/docs/api/subscription-preferences/get-subscription-preferences /api/subscription-categories/subscription-categories.yaml get /category-subscription/user-preferences This API fetches the subscription category preferences information for a specific user based on the encrypted User ID and Campaign ID found in the landing page URL. #### Rate Limit The rate limit is 100 RPM and 360k per day. # Update Subscription Preferences Source: https://moengage.com/docs/api/subscription-preferences/update-subscription-preferences /api/subscription-categories/subscription-categories.yaml put /category-subscription/user-preferences This API updates the subscription category preferences for a specific user who navigates from an email. This endpoint requires the encrypted IDs obtained from the email link. #### Rate Limit The rate limit is 100 RPM and 360k per day. # Create Push Template Source: https://moengage.com/docs/api/templates/create-push-template /api/push-templates/push-templates.yaml post /custom-templates/push This API creates a new push notification template for one or more platforms (Android, iOS). #### Rate Limit The rate limit is 100 RPM (Requests Per Minute). # Search for Push Templates Source: https://moengage.com/docs/api/templates/search-for-push-templates /api/push-templates/push-templates.yaml post /custom-templates/push/search This API searches the push templates created in your MoEngage account. We are introducing mandatory pagination, effective November 15, 2025, all calls to this API must include the following two parameters: * **page**: The page number of the results you wish to fetch. * **entries**: The number of templates to return per page, with a maximum value of 15. Please update all integrations to include these parameters. API requests submitted without them after the effective date will result in an error and fail to execute. #### Rate Limit The rate limit is 100 RPM (request per minute). # Update Push Template Source: https://moengage.com/docs/api/templates/update-push-template /api/push-templates/push-templates.yaml put /custom-templates/push This API updates an existing push notification template by creating a new version. #### Rate Limit The rate limit is 100 RPM (Requests Per Minute). # Personalized Preview Source: https://moengage.com/docs/api/test-campaigns/personalized-preview /api/campaigns/campaigns.yaml post /personalization/preview 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. #### 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. # Test Campaign Source: https://moengage.com/docs/api/test-campaigns/test-campaign /api/campaigns/campaigns.yaml post /campaigns/test 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. # Track App Install Source: https://moengage.com/docs/api/tracking/track-app-install /api/data/data.yaml get /installInfo This API tracks the install attribution data in MoEngage, which you can then use to enhance your marketing automation campaigns on MoEngage. Install attribution tracking is a great way to improve your initial relationship with your user. Knowing how, where, and even more importantly, why a user installs your app allows you to get a better understanding of who your user is and how you should introduce them to your app. # Send Transactional Alert Source: https://moengage.com/docs/api/transactional-alerts/send-transactional-alert /api/inform/inform.yaml post /alerts/send This API is used to trigger a transactional message/alert to the user via one or more configured channels. #### Rate Limit The default rate limit is 10K RPM. # Send Push Notification Source: https://moengage.com/docs/api/transactional/send-push-notification /api/push/push.yaml post /transaction/sendpush This API creates and sends a push notification campaign. You can use this API to create campaigns (targeting all users or a group of users) to send notifications, target a single user using a unique user attribute, and personalize payload for each user. #### Rate Limit The rate limit is 10,000 requests per minute. #### Authentication A signature is required to verify whether the client is authorized to make the API call. It is generated from a hash of the campaign name, app ID, and API key. MoEngage uses the SHA 256 method to generate this hash. Python code is used to generate the signature for your test account, and use your account's app\_id. 1. On the left navigation menu in the MoEngage dashboard, go to **Settings** > **Account** > **APIs**. 2. Copy the following details: * **app\_id**: Under **Workspace ID (earlier app\_id)**, click the copy icon to copy the app-id. * **api\_key**: In the **API keys** section, click the copy icon in the **Push** tile to copy the API key. * **campaign\_name**: Ensure the campaign name matches the one used in the request body. ### Generating Signature Python code to generate the signature for your test account, use the app\_id that is appropriate for your account. ```python from hashlib import sha256 app_id = "{{Your Workspace ID}}" campaign_name = "{{your campaign name}}" api_key = "{{your push api key}}" signature_key = app_id+'|'+ campaign_name+'|'+ api_key signature = sha256(signature_key.encode('utf-8')).hexdigest() print(signature) ``` ```python from hashlib import sha256 app_id = "{{Your Workspace ID}}" campaign_name = "{{your campaign name}}" api_key = "{{your push api key}}" signature_key = app_id+'|'+ campaign_name+'|'+ api_key signature = sha256(signature_key).hexdigest() print(signature) ``` # Change Campaign Status Source: https://moengage.com/docs/api/update-campaigns/change-campaign-status /api/campaigns/campaigns.yaml post /campaigns/status 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). 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 #### Rate Limit Maximum 10 campaign IDs can be processed per request. # Update Campaign Source: https://moengage.com/docs/api/update-campaigns/update-campaign /api/campaigns/campaigns.yaml patch /campaigns/{campaign_id} 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. **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. # Delete Users Source: https://moengage.com/docs/api/user/delete-users /api/data/data.yaml post /customer/delete This API deletes users in MoEngage. You cannot retrieve users once deleted. Users deleted (hard delete) using this API will be deleted after a default buffer of 24 hours. During this buffer period, the user will still be active in MoEngage and will be visible in Segments, Analytics, and Campaigns. You can update users in the buffer period. After the buffer elapses, the user is hard-deleted from MoEngage. If you create a user with the same unique identifiers as the deleted one in MoEngage (through APIs or imports), they will be created again in MoEngage. #### Rate Limit The rate limit is 1 user per payload per request. You can run 5000 requests per minute. # Get User Source: https://moengage.com/docs/api/user/get-user /api/data/data.yaml post /customers/export This API facilitates the retrieval of information of users by specifying the user IDs. #### Rate Limit The rate limit is 20 users per payload and 1000 users per minute. # Merge Users Source: https://moengage.com/docs/api/user/merge-users /api/data/data.yaml post /customer/merge This API merges two users in MoEngage based on their ID, which is a client-defined identifier for a user. You can use this API when multiple profiles have been created for a single user. For example, you can merge a user registered once with a mobile number and once with an email ID. You can also merge duplicate users created due to integration or tech issues. #### Types of user merging in MoEngage * Default or normal merge: * MoEngage merges users with the same ID. * Happens automatically, and no action is required from your side. * Manual merge: * MoEngage merges users having different IDs. * Does not happen automatically; you must call the Merge User API with the list of users to be merged along with their IDs. - User Merging is a complex functionality and, if misused, can lead to data integrity issues. If the data passed to the API is incorrect, resulting in a merge of two unintended users, MoEngage will not be able to recover/rectify the data. The retained user would have erroneous data, and segmentation queries would not provide the right results. - MoEngage does not support transitive/canonical merging. For example, if user A is merged to B (A ->B) and then user B is merged to C (B ->C), in this scenario, events of user A are not moved to user C. - The Merge User API is not functional in workspaces where the [Identity Resolution](https://help.moengage.com/hc/en-us/articles/24050999467284-Unified-Identity-Identity-Resolution) feature is enabled. - If you are updating the [Unique Identifier](https://developers.moengage.com/hc/en-us/articles/4404440336148-Tracking-User-Attributes) for a user, use the Merge User API at least 2 hours after you have updated the Unique Identifier. - Ensure that the data passed to the API is accurate. We recommend you test the merging starting with a small batch of users, such as 1, 5, 10, 20, 50, etc. Verify the merged data and users before proceeding with a bulk update. #### Rate limit The rate limit is 1000 user updates per minute. # Track User Source: https://moengage.com/docs/api/user/track-user /api/data/data.yaml post /customer/{app_id} This API adds or updates users and user properties in MoEngage. You can create a new user, create new user property, or update existing user properties of users. If you have [Portfolio](https://help.moengage.com/hc/en-us/articles/40394603054100-Portfolio) enabled for your workspace, you must pass `project_code` in the API endpoint. This identifies which project a user or event belongs to. For more information, refer to [Portfolio: Data Ingestion and Management](https://help.moengage.com/hc/en-us/articles/40358246598804-Portfolio-Data-Ingestion-and-Management). #### Rate Limit A single API request contains one or more user updates. Maintain a rate limit of 10,000 user updates per minute. # Test Connection API Source: https://moengage.com/docs/api/utilities/test-connection-api /api/data/data.yaml post /integrations/authentication This API validates if the entered endpoint details are valid. It verifies if the provided endpoint URL, workspace ID, and data key are accessible and responds without any errors. # Android TV Source: https://moengage.com/docs/developer-guide/android-sdk/android-tv/android-tv Integrate MoEngage features like data tracking, in-app messages, and cards into your Android TV app. MoEngage supports your apps available on Android TV. Ensure that the [Android SDK integration](/developer-guide/android-sdk/sdk-integration/basic-integration/sdk-initialization) is completed. # Supported Features MoEngage supports the following: * [Data Tracking](/developer-guide/android-sdk/data-tracking) * [HTML In-App](/developer-guide/android-sdk/in-app-messages/in-app-nativ) * [Self-handled InApp](/developer-guide/android-sdk/in-app-messages/in-app-nativ) * [Self-handled Cards](/developer-guide/android-sdk/cards/self-handled-cards) # Cards Source: https://moengage.com/docs/developer-guide/android-sdk/cards/cards Set up MoEngage Cards to deliver persistent inbox and newsfeed messages to your Android app users. Create targeted or automated App Inbox/NewsFeed messages that can be grouped into various categories, and target your users with different updates or offers that can stay in the Inbox/Feed over a designated period of time. For more information, refer to [Cards](https://help.moengage.com/hc/en-us/articles/360045074752-Create-Cards-Campaign). Android Cards # SDK Installation ## Install using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/developer-guide/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the app/build.gradle file as shown below ```kotlin build.gradle.kts wrap theme={null} dependencies { implementation("com.moengage:cards-core") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. ### **SDK Dependency on Glide for Image and GIF Loading** SDK uses [Glide](https://bumptech.github.io/glide/) for loading images and gifs. Ensure you add Glide to your application in case you don't have it already. SDK is compiled using library version **4.9.0.** We recommend you use the same version or higher in your application. # Adding the UI Component You can integrate the card UI into your application either by inflating the activity provided by the SDK or attaching the Fragment provided by the SDK to an existing Activity in the application. ## Integrating using Activity The SDK manifest has declared the [*CardActivity*](https://moengage.github.io/android-api-reference/cards-ui/com.moengage.cards.ui/-card-activity/index.html) in the manifest file, and nothing additional is required until and unless you want to customize the theme of the Activity or any other launch property.\ The default declaration is as below. ```xml AndroidManifest.xml wrap theme={null} ``` For more information about how to customize, refer to Customisation. ## Integrating using Fragment To integrate the Card UI as a fragment, you can inflate the [*CardFragment*](https://moengage.github.io/android-api-reference/cards-ui/com.moengage.cards.ui/-card-fragment/index.html) from the appropriate place inside your application. # UI Customizations SDK provides a certain set of UI customizations. ## Activity Customization If you are integrating the activity provided by the SDK, you can customize the label, theme, etc.\ To customize the theme label you can either re-declare the activity in your app's manifest and provide the desired theme or label.\ Alternatively, you can override the SDK defaults as described below. ### Activity Label The default label for the activity is **Inbox**. In case you want to change the label add the **moe\_card\_feed\_title** string in your **strings.xml** file with the label name. ```markdown strings.xml wrap theme={null} [YOUR_LABEL_NAME] ``` ### Activity Theme The default theme applied to the Activity is **MoECardTheme.NoActionBar**.\ The following is the theme definition. ```xml colors.xml wrap theme={null} ``` The background color of the toolbar is set to the primary color of the theme. ## Tab Customisation The Card UI is built with a tab layout, following is the list of customization options provided by the SDK. * Text Appearance * Font * Text Size * Tab Text-color selected/unselected * Tab background-color selected/unselected To customize the properties, you can override the styles or color attributes defined by the SDK in your application **colors.xml** or **styles.xml** file. ```xml style.xml wrap theme={null} ``` ```xml colors.xml wrap theme={null} #1C64D0 #8E8E8E @color/moe_white @color/moe_white ``` ## Text Customization Each card has three text fields and a button * Header * Message * Call to Action Button(CTA) * Timestamp The default style for each of these components can be overridden by overriding the below styles completely or overriding the individual items.\ Certain styling components like color and text formatting (like bold, italic, etc.) for these fields are customizable from the MoEngage Dashboard, while others, like font and text size fixed on the SDK side. Values for these can be overridden and will be applied to all cards. The color defined in these styles are default colors and will be overridden by the colors selected during campaign creation. ```xml styles.xml wrap theme={null} {/* Header style */} {/* Message style */} {/* Button style */} {/* Timestamp Style */} ``` ```xml colors.xml wrap theme={null} {/* Text Color */} #424242 #616161 #9E9E9E ``` ### Timestamp format Customization The default format for the timestamp shown on each card is **MMM dd, hh:mm a** this can be customized by passing the custom format to [*configureCards()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-cards.html) of the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html)object while initializing the SDK. ## Card Customization You can customize the following properties for a given card * Un-clicked Indicator Color * Card Background Color (overridden by the color selected during the campaign creation) Override the below color resources in the **colors.xml** to use the desired color. ```xml colors.xml wrap theme={null} #5956D6 @color/moe_white ``` ## Empty State If the inbox does not contain any cards, SDK shows an empty screen with an image and message, as shown below. Emptystate The image and message can be customized if required. #### Image Customization To customize the image, pass in the resource id of the image in the [*configureCards()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-cards.html) API [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) object while initializing the SDK. #### Message Customisation To customize the message, override the **moe\_card\_no\_message\_available** in your applications **strings.xml** file. ```xml strings.xml wrap theme={null} [YOUR_STRING_GOES_HERE] ``` ## Customize Delete Text To customize the message of the delete button, override the below string resource in the **strings.xml** of your application. ```xml xml wrap theme={null} [YOUR_STRING_GOES_HERE] ``` ## Disable Pull to Refresh By default, the Card Activity/Fragment has the pull to refresh feature enabled, you can disable pull to refresh using the [*configureCards()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-cards.html)API in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html)*.* # APIs ## Unclicked Count The SDK provides an API to fetch the number of cards which hasn't been clicked by the users. To get the count, you can use the below APIs. ```Kotlin Kotlin wrap theme={null} // Call this API on worker thread as it reads from a file. MoECardHelper.getUnClickedCardCount(context) // This API returns the count asynchronously in the listener passed as a parameter. MoECardHelper.getUnClickedCardCountAsync(context, listener) ``` ```Java Java theme={null} // Call this API on worker thread as it reads from a file. MoECardHelper.INSTANCE.getUnClickedCardCount(context); // This API returns the count asynchronously in the listener passed as a parameter. MoECardHelper.INSTANCE.getUnClickedCardCountAsync(context, listener); ``` Refer to the documentation of [*MoECardHelper.getUnClickedCardCount()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-un-clicked-card-count.html) and [*MoECardHelper.getUnClickedCardCountAsync()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-un-clicked-card-count-async.html) for more information. ## New Card Count The SDK provides an API to get the new cards for the user on the device. To get the count, use the below API. ```Kotlin Kotlin wrap theme={null} // Call this API on worker thread as it reads from a file. MoECardHelper.getNewCardCount(context) // This API returns the count asynchronously in the listener passed as a parameter. MoECardHelper.getNewCardCountAsync(context, listener) ``` ```Java Java theme={null} // Call this API on worker thread as it reads from a file. MoECardHelper.INSTANCE.getNewCardCount(context); // This API returns the count asynchronously in the listener passed as a parameter. MoECardHelper.INSTANCE.getNewCardCountAsync(context, listener); ``` Refer to the documentation of [*MoECardHelper.getNewCardCount()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-new-card-count-async.html)and [*MoECardHelper.getNewCardCountAsync()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-new-card-count-async.html) for more information. # Callbacks The SDK provides callbacks when * Cards are successfully synced on application launch/foreground * The card is clicked by the user ## Sync Callback To get a callback for sync completion on application launch/foreground implement the [*SyncCompleteListener*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core.listener/-sync-complete-listener/index.html) interface and register for the callback using [*MoECardHelper.setSyncCompleteListener()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/set-sync-complete-listener.html)*.* ## Click Callback To get a callback on the card, click implement the [*OnCardClickListener*](https://moengage.github.io/android-api-reference/cards-ui/com.moengage.cards.ui.listener/-on-card-click-listener/index.html) interface and register for the callback using the [*MoECardUiHelper.setClickListener().*](https://moengage.github.io/android-api-reference/cards-ui/com.moengage.cards.ui/-mo-e-card-ui-helper/set-click-listener.html) # Self Handled Cards Source: https://moengage.com/docs/developer-guide/android-sdk/cards/self-handled-cards Build custom card views in your Android app using the MoEngage self-handled Cards SDK. Self-handled cards give you the flexibility of creating Card Campaigns on the MoEngage Platform and displaying the cards anywhere inside the application. SDK provides APIs to fetch the campaign's data using which you can create your own view for cards. # SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/developer-guide/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```kotlin build.gradle.kts wrap theme={null} dependencies { ... implementation("com.moengage:cards-core") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. # Implementing Self Handled Cards Use the below APIs to fetch the card's data and build your own UI. The SDK provides both blocking and async APIs for fetching the data. In this document, we have just added the blocking APIs, refer to the API reference for [*MoECardHelper*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/index.html) for the async APIs. ## Notify on Section Load/Unload You can show the cards on a separate screen or a section of the screen. When the cards screen/section is loaded call [*onCardSectionLoaded()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/on-card-section-loaded.html) and call [*onCardSectionUnloaded()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/on-card-section-unloaded.html) when the screen/section is no longer visible or going to background. ```Kotlin Kotlin wrap theme={null} // call on section or screen load MoECardHelper.onCardSectionLoaded(context,listener); // call when the section is no longer visible or going to background. MoECardHelper.onCardSectionUnloaded(context); ``` ```Java Java theme={null} // call on section or screen load MoECardHelper.INSTANCE.onCardSectionLoaded(context,listener); // call when the section is no longer visible or going to background. MoECardHelper.INSTANCE.onCardSectionUnloaded(context); ``` ## Fetch Categories To fetch all the categories for which cards are configured, use the [*getCardCategories()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-card-categories.html) API. ```Kotlin Kotlin wrap theme={null} MoECardHelper.getCardCategories(context) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.getCardCategories(context); ``` Additionally, you can optionally have an **All** category which would be like a superset of other categories. Use the [*isAllCategoryEnabled()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/is-all-category-enabled.html) API. ```Kotlin Kotlin wrap theme={null} MoECardHelper.isAllCategoryEnabled(context) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.isAllCategoryEnabled(context); ``` ## Fetch Cards for Categories To fetch cards eligible for display for a specific category, use the [*getCardsForCategory()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-cards-for-category.html) API ```Kotlin Kotlin wrap theme={null} MoECardHelper.getCardsForCategory(context, "[YOUR_CATEGORY]") ``` ```Java Java theme={null} MoECardHelper.INSTANCE.getCardsForCategory(context, "[YOUR_CATEGORY]"); ``` To fetch all the cards eligible for display irrespective of the category, pass the category **CARD\_CATEGORY\_ALL** as shown below ```Kotlin Kotlin wrap theme={null} MoECardHelper.getCardsForCategory(context, CARDS_CATEGORY_ALL) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.getCardsForCategory(context, MoECardsCoreConstants.CARDS_CATEGORY_ALL); ``` Refer to the documentation of the [*Card*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core.model/-card/index.html) model to know more about the fields and data present. Instead of using separate APIs to fetch the Cards and categories, you can use the [*getCardsInfo()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/get-cards-info.html) API to fetch all the information in one go ```Kotlin Kotlin wrap theme={null} MoECardHelper.getCardsInfo(context) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.getCardsInfo(context); ``` ## Widget and Widget Id Mapping ### Basic Card/Illustration Card | Widget Id | Widget Type | Widget Information | | --------- | -------------------------- | --------------------------------- | | 0 | Image (WidgetType.IMAGE) | Image widget in the card. | | 1 | Text (WidgetType.TEXT) | Header text for the card. | | 2 | Text (WidgetType.TEXT) | Message text for the card. | | 3 | Button (WidgetType.Button) | Call to action(CTA) for the card. | ## Track Statistics for Cards Since the UI/display of the cards is controlled by the application to track statistics on delivery, display, and click, we need the application to notify the SDK. ### Delivered To track delivery to the card section of the application, call the [*cardDelivered()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/card-delivered.html) API when the cards section of the application is loaded. ```Kotlin Kotlin wrap theme={null} MoECardHelper.cardDelivered(context) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.cardDelivered(context); ``` ### Impression Call the [*cardShown()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/card-shown.html) API when a specific card is visible on the screen. ```Kotlin Kotlin wrap theme={null} MoECardHelper.cardShown(context, card) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.cardShown(context, card); ``` ### Click Call the [*cardClicked()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/card-clicked.html) API whenever a user clicks on a card, along with the card object widget identifier for the UI element clicked should also be passed.  ```Kotlin Kotlin wrap theme={null} MoECardHelper.cardClicked(context, card, widgetId) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.cardClicked(context, card, widgetId); ``` ## Delete Card Call the [*deleteCard()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/delete-card.html) API to delete a card ```Kotlin Kotlin wrap theme={null} MoECardHelper.deleteCard(context, card) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.deleteCard(context, card); ``` To delete a list of cards, use [*deleteCards()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/delete-cards.html) API. ## Refresh Cards from the Server Use the [*fetchCards()*](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/fetch-cards.html) API to refresh cards from the MoEngage server if required. ```Kotlin Kotlin wrap theme={null} MoECardHelper.fetchCards(Context, CardAvailableListener) ``` ```Java Java theme={null} MoECardHelper.INSTANCE.fetchCards(Context, CardAvailableListener); ``` * The SDK automatically refreshes/fetches cards from the MoEngage server whenever the application comes to the foreground. * This API has a FUP if breached the existing cards i.e. the ones in the local storage of the device will be passed on in the callback. Please take a look at the [documentation](https://moengage.github.io/android-api-reference/cards-core/com.moengage.cards.core/-mo-e-card-helper/index.html) for a complete guide on available helper APIs. # Release checklist Source: https://moengage.com/docs/developer-guide/android-sdk/checklist/release-checklist Verify your MoEngage Android SDK integration against this checklist before releasing your app. Before releasing your application with MoEngage SDK integrated verify if the following items have been implemented. # General * SDK is initialized in *onCreate()* of the Application class on the Main Thread. * Disable logging for release build if enabled. * Enable Java 8 target and source compatibility. # Data Tracking * Install/Update Differentiation * Exhaustive Events and Attributes are tracked based on use-cases. * User attributes tracked for both new and existing users * Track the unique identifier for the user on login using *setUniqueId()* * The logout method is called when the user is logged out of the application # Push Notification ## FCM * Firebase messaging dependency added and related Firebase plugins added. * Small icon and large icon set along with other optional metadata * In case you are using vector drawables, .webp or any file format other than .png images for notification icons, please make sure you have tested on all OS versions supported by your app. * Check Firebase receiver in the **AndoidManifest.xml** file. Make sure only 1 receiver is added in the manifest file. * Test Push on a physical device * Token Registration and Payload handled by App * Disable token registration of MoEngage SDK * Token passed to the SDK for a fresh install, app update, and whenever FCM refreshes the token. * Push Payload passed on to the SDK * Token Registration and Payload handled by SDK * SDK's FCM receiver added in the manifest * Token change listener registered if required. ## Push Amp Plus ### Mi * Check version compatibility of Mi push dependency with **moe-android-sdk** * Configured App Key and App-id during SDK initialization * Test on Mi Device * Token Registration and Payload handled by App * Disable token registration of MoEngage SDK * Token passed to the SDK for a fresh install, app update, and whenever Mi refreshes the token. * Push Payload passed on to the SDK * Token Registration and Payload handled by SDK * SDK's Mi receiver is added in the manifest. * Token change listener registered if required. ### Push Kit * Push Kit dependency added and related HMS plugins configured. * Check version compatibility of PushKit dependency with **moe-android-sdk** * Test on Huawei Device ## Push Templates * Check version compatibility of the Push Templates dependency with **moe-android-sdk** * Test a template campaign on the device. # In-App * Check version compatibility of the Push Templates dependency with **moe-android-sdk** * Call *showInApp()* on all Activity or Fragment where you want to show In-Apps * NudgeView is embedded in the required Activity or Fragment. * Test In-App Campaigns on a device. # Inbox * Check version compatibility of Inbox dependency with **moe-android-sdk** * Check if campaigns are visible in the applications inbox. # Cards * Check version compatibility of the Cards dependency with **moe-android-sdk** * Check if card campaigns are visible on the device. # Geofence * Check version compatibility of the Geofence dependency with **moe-android-sdk** * Application has added Google’s Location Services as a dependency in the application. * Application requests appropriate permissions based on the OS version. # Compliance Source: https://moengage.com/docs/developer-guide/android-sdk/compliance/compliance Enable or disable data tracking and manage user consent in the MoEngage Android SDK. # Enable/Disable Data Tracking If you don't want the MoEngage SDK not to track user data to the MoEngage System use the [disableDataTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]disable-data-tracking.html) API. ```kotlin Kotlin wrap theme={null} import com.moengage.core.disableDataTracking disableDataTracking(context) ``` ```java Java theme={null} MoESdkStateHelper.disableDataTracking(context); ``` Once the above API is called, no custom events or user attributes will be tracked. SDK will reject all events until [enableDataTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]enable-data-tracking.html) is called.\ Once you want to track events or user attributes, call the below API. ```kotlin Kotlin wrap theme={null} import com.moengage.core.enableDataTracking enableDataTracking(context) ``` ```java Java theme={null} MoESdkStateHelper.enableDataTracking(context); ``` # Enable/Disable SDK If you don't want the MoEngage SDK not to track any user information or send any data to the MoEngage System, use the [disableSdk()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]disable-sdk.html) API. ```kotlin Kotlin wrap theme={null} import com.moengage.core.disableSdk disableSdk(context) ``` ```java Java theme={null} MoESdkStateHelper.disableSdk(context); ``` Once this API is called, all the SDK APIs will be non-operational. SDK will be disabled until [enableSdk()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]enable-sdk.html) is called.\ Once you have the user's consent use the below API to enable the SDK. ```kotlin Kotlin wrap theme={null} import com.moengage.core.enableSdk enableSdk(context) ``` ```java Java theme={null} MoESdkStateHelper.enableSdk(context); ``` # Delete User Data In April 2023, Google Announced the [User Account Deletion Policy](https://android-developers.googleblog.com/2023/04/giving-people-more-control-over-their-data.html), according to which if your app allows you to create an account within your app, it must also allow the user to delete their account within the app. Calling this API will delete the User Data/Profile from the MoEngage Server. You need to have a minimum SDK version of **12.10.00** or **above**to call this API. ```kotlin Kotlin wrap theme={null} import com.moengage.core.MoECoreHelper MoECoreHelper.deleteUser(context,listener) ``` ```kotlin Java theme={null} import com.moengage.core.MoECoreHelper; MoECoreHelper.INSTANCE.deleteUser(context,listener); ``` For more information, refer to the [API Documentation.](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-e-core-helper/delete-user.html) # Prepare for Google Play's data disclosure requirements Source: https://moengage.com/docs/developer-guide/android-sdk/compliance/prepare-for-google-plays-data-disclosure-requirements Review MoEngage Android SDK data collection details to complete Google Play's Data Safety disclosure. In May 2021, Google Play [announced the new Data safety section](https://android-developers.googleblog.com/2021/05/new-safety-section-in-google-play-will.html), which is a developer-provided disclosure for an app's data collection, sharing, and security practices. This page can help you complete the requirements for this data disclosure in regards to your usage of the MoEngage Android SDK. On this page, you can find information on whether and how our SDK handles end-user data, including any applicable settings or configurations you can control as the application developer. We aim to be as transparent as possible in supporting you; however, as the application developer, you are solely responsible for deciding how to respond to Google Play's Data safety section form regarding your app's end-user data collection, sharing, and security practices. # How to use the information on this page? This page lists the end-user data collected only from *version **12.2.01*** of the MoEngage Android SDK. If you are using a prior version of the MoEngage Android SDK, could you update to the latest version to ensure your app's disclosures are accurate? The MoEngage Android SDK will continue to be updated over time. This article will reflect these changes, so update your disclosures as necessary. # Data collected ## Mandatory Data Collected SDK collects the following data automatically for analytics. | Data | By default, MoEngage SDK ... | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | IP Address | Collects the device's IP address, which may be used to estimate the general location of a device. | | User product interactions | Collects user-product interactions and interaction information, including app launch, and application foreground-background. | | Device Metadata | Collects device information like Device Model, OS version, Timezone, network type(if permission is granted by the user), | ## Optional Data Collected SDK optionally collects the below data based on whether the application/user has given consent for tracking the data.  | Data | MoEngage SDK... | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | | Device Metadata | Collects device information like Product Name, Manufacturer,  Device Dimensions, Display type, and Carrier(if permission is granted by the user). | | Device Identifiers | Collects device identifiers like Advertising Identifier, and Android Id. | # Configuring Opt-outs Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/advanced-or-optional/configuring-opt-outs Configure tracking opt-outs for device identifiers like GAID and Android ID in the MoEngage Android SDK. By default, SDK tracks certain device identifiers like GAID, Android-id, activity names, etc. If required you can choose to opt-out of this tracking by using the TrackingOptOutConfig.\ Refer to the API reference of [TrackingOptOutConfig](https://moengage.github.io/android-api-reference/core/com.moengage.core.config/\[android-jvm]-tracking-opt-out-config/index.html) for more details on the available opt-outs. Use the [configureTrackingOptOut()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-tracking-opt-out.html) to pass on the configuration to the SDK. ```Kotlin Kotlin wrap theme={null} val trackingOptOut = mutableSetOf>() trackingOptOut.add(YourActivityName::class.java) val trackingOptOutConfig = TrackingOptOutConfig( isCarrierTrackingEnabled = true, isDeviceAttributeTrackingEnabled = true, trackingOptOut ) val moengage = MoEngage.Builder(application, appId) .configureTrackingOptOut(trackingOptOutConfig) .build() MoEngage.initialise(moengage) ``` ```Java Java theme={null} Set> trackingOptOut = new HashSet<>(); trackingOptOut.add(YourActivityName.class); MoEngage moEngage = new Builder(application, ConstantsKt.APP_ID) .configureFcm(new FcmConfig(true)) .configureTrackingOptOut(new TrackingOptOutConfig(true, true, trackingOptOut)) .build(); MoEngage.initialise(moEngage); ``` # Device Identifier Tracking Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/advanced-or-optional/device-identifier-tracking Enable or disable Android ID and advertising identifier tracking in the MoEngage Android SDK. ## Android Id Tracking From SDK version **11.5.00**, SDK optionally tracks Android-id for the devices(by default Android-id is not tracked). To enable Android-id tracking use the [enableAndroidIdTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]enable-android-id-tracking.html) method as shown below. ```Kotlin Kotlin wrap theme={null} import com.moengage.core.enableAndroidIdTracking enableAndroidIdTracking(context) ``` ```Java Java theme={null} MoESdkStateHelper.enableAndroidIdTracking(context); ``` Before enabling the Android-id tracking application should take consent from the user as per the [Google Policy](https://support.google.com/googleplay/android-developer/answer/10144311).Once tracking is enabled SDK would continue tracking the Android-id until explicitly opted-out. Use the [disableAndroidIdTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]disable-android-id-tracking.html) method to opt-out of Android-id tracking. ```Kotlin Kotlin wrap theme={null} import com.moengage.core.disableAndroidIdTracking disableAndroidIdTracking(context) ``` ```Java Java theme={null} MoESdkStateHelper.disableAndroidIdTracking(context); ``` For the SDK version below **11.5.00** use the *TrackingOptoutConfig* while initializing the MoEngage SDK. ## Advertising Identifier Tracking From SDK version **12.1.00**, SDK optionally tracks Advertising Identifier for the devices(by default Advertising Identifier is not tracked). To enable Advertising Identifier tracking use the [enableAdIdTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]enable-ad-id-tracking.html) method as shown below. ```Kotlin Kotlin wrap theme={null} import com.moengage.core.enableAdIdTracking enableAdIdTracking(context) ``` ```Java Java theme={null} MoESdkStateHelper.enableAdIdTracking(context); ``` Before enabling the Advertising Identifier tracking application should take consent from the user as per the [Google Policy](https://support.google.com/googleplay/android-developer/answer/10144311). Once tracking is enabled SDK would continue tracking the Advertising Identifier until explicitly opted-out. Use the [disableAdIdTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]disable-ad-id-tracking.html) method to opt-out of Advertising Identifier tracking. ```Kotlin Kotlin wrap theme={null} import com.moengage.core.disableAdIdTracking disableAdIdTracking(context) ``` ```Java Java theme={null} MoESdkStateHelper.disableAdIdTracking(context); ``` For the SDK version below **12.1.00** use the *TrackingOptoutConfig* while initializing the MoEngage SDK. # Offerings Events Tracking Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/advanced-or-optional/offerings-events-tracking Track impression and click events for MoEngage Offerings fetched via the Personalize API on Android. This document outlines the new methods available in the MoEngage Android SDK to report impressions and clicks for Offerings fetched using the [MoEngage Personalize API](https://www.moengage.com/docs/api/experiences/fetch-experience). # Prerequisites ## SDK version > You must update your Native Android SDK catalog version to **5.3.1** or higher. ## MoEngage Account Configuration Ensure your MoEngage workspace is enabled to utilize Offerings. Refer to [this article](https://help.moengage.com/hc/en-us/articles/38661119123732-Offerings) for details on setting up Offerings. # Reporting Offering Shown events The SDK provides a helper API to track shown events; please refer to the [API documentation](https://moengage.github.io/android-api-reference/campaigns-core/com.moengage.campaigns.personalize/-mo-e-personalize-helper/offering-shown.html) for more details. Impressions should be reported when an Offering is visually presented to the user. To report an impression offering, pass the **offeringContext** as a map. ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.offeringShown(context, offeringContextMap) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.offeringShown(context, offeringContextMap); ``` # Reporting Offering Clicked events The SDK provides a helper API to track clicked events; refer to the [API documentation](https://moengage.github.io/android-api-reference/campaigns-core/com.moengage.campaigns.personalize/-mo-e-personalize-helper/offering-clicked.html) for more details. Clicked events should be reported when a user clicks on any offering contained in the response of the Personalize API. To report a click event for a single offering, pass the **offeringContext** of the offering as a map. When a user clicks on an Offering, we understand that they are also implicitly clicking on the parent Experience. You can now optionally pass the experienceContext to the**offeringClicked**function. ### **What this means** * **If you pass both contexts,** MoEngage will **automatically** track clicks for **both** the Offering and the Experience. You no longer need to make a second, separate call to track the click event for the parent experience. * **If you only pass the offeringContext,** the **experienceContext** is optional. If you don't pass it, we will only track the click for the Offering. You would then need to track the experience click separately, if required. ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.offeringClicked(context, offeringContextMap, experienceContextMap) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.offeringClicked(context, offeringContextMap, experienceContextMap); ``` # Personalize Experience Events Tracking Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/advanced-or-optional/personalize-experience-events-tracking Track impression and click events for personalized experiences from the MoEngage Personalize API on Android. This document outlines the new methods available in the MoEngage Android SDK to report impressions and clicks for experiences fetched using the [MoEngage Personalize API](https://www.moengage.com/docs/api/experiences/fetch-experience). # Prerequisites ## SDK version > You must update your Native Android SDK catalog version to **5.2.0** or higher. ## MoEngage Account Configuration Ensure your MoEngage workspace is enabled to utilize the Personalize API. Refer to [this article](https://help.moengage.com/hc/en-us/articles/24644175705236-Create-Server-side-Personalization-Experience) for details on setting up Personalize API experiences. # Reporting Experience Shown events The SDK provides helper APIs to track shown events; please refer to the [API documentation](https://moengage.github.io/android-api-reference/campaigns-core/com.moengage.campaigns.personalize/-mo-e-personalize-helper/index.html) for more details. Impressions should be reported when an experience is visually presented to the user. ## Single Experience To report an impression for a single experience, pass the **experience\_context** of the experience as a map. **experience\_context** is a JSON object that is returned as part of the [response of the Personalize API request](https://www.moengage.com/docs/api/experiences/fetch-experience). ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.experienceShown(context, experienceContextMap) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.experienceShown(context, experienceContextMap); ``` ## Mulitple Experiences To track the experience shown event for multiple experiences, pass the **list** of **experience\_context** of each experience as a map. ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.experienceShown(context, experienceContextMapList) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.experienceShown(context, experienceContextMapList); ``` # Reporting Experience Clicked events The SDK provides helper APIs to track clicked events; refer to the [API documentation](https://moengage.github.io/android-api-reference/campaigns-core/com.moengage.campaigns.personalize/-mo-e-personalize-helper/index.html) for more details. Clicked events should be reported when a user clicks on any element that has been personalized using the response of the Personalize API. ## Single Experience To report a click event for a single experience, pass the **experience\_context** of the experience as a map. ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.experienceClicked(context, experienceContextMap) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.experienceClicked(context, experienceContextMap); ``` ## Mulitple Experiences To track the experience shown event for multiple experiences, pass the **list** of **experience\_context** of each experience as a map. ```Kotlin Kotlin wrap theme={null} MoEPersonalizeHelper.experienceClicked(context, experienceContextMapList) ``` ```Java Java wrap theme={null} MoEPersonalizeHelper.INSTANCE.experienceClicked(context, experienceContextMapList); ``` You can optionally include a **b\_id** key in the **experience\_context** object to provide additional context about the click. Its value should describe the specific component or interaction within the experience that was clicked. This is particularly useful for experiences composed of multiple interactive elements, helping to distinguish between clicks on different parts of the same overall experience. # Tracking Locale Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/advanced-or-optional/tracking-locale Optionally track the device locale in your Android app using the MoEngage SDK. **Optional** This is optional and only required if you wish to track the locale. SDK by default does not track locales. To track the Locale set for the given JVM instance call [MoEAnalyticsHelper.trackDeviceLocale()](https://moengage.github.io/android-api-reference/core/com.moengage.core.analytics/\[android-jvm]-mo-e-analytics-helper/track-device-locale.html). ```Kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.trackDeviceLocale(context) ``` ```Java Java wrap theme={null} MoEAnalyticsHelper.INSTANCE.trackDeviceLocale(context); ``` # Enable Advertising Identifier Tracking Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/basic/enable-advertising-identifier-tracking Enable advertising identifier tracking in the MoEngage Android SDK for accurate device analytics. For accurate analytics around devices and tracking Re-installs, it is essential to track the Advertising Identifier. For more information, refer to [Android Advertising ID Tracking](https://help.moengage.com/hc/en-us/articles/7457641031828-Android-Advertising-ID-Tracking). ## Add Ad Identifier Library Add the below dependency in the application-level ***build.gradle*** file. ```groovy Groovy wrap theme={null} implementation("com.google.android.gms:play-services-ads-identifier:18.0.1") ``` To enable Advertising Identifier tracking use the [enableAdIdTracking()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]enable-ad-id-tracking.html) method as shown below. ```Kotlin Kotlin wrap theme={null} import com.moengage.core.enableAdIdTracking enableAdIdTracking(context) ``` ```Java Java wrap theme={null} MoESdkStateHelper.enableAdIdTracking(context); ``` Please ensure the application is complying with the [Google Play Policy](https://support.google.com/googleplay/android-developer/answer/10144311) regarding Advertising Id tracking. # Setting Unique Id for SDK versions below 13.6.00 Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/basic/setting-unique-id-for-sdk-versions-below-13-6-00 Set a unique user ID for login and logout in MoEngage Android SDK versions below 13.6.00. # Implementing Login/Logout * It's important to set the User Attribute Unique ID when a user logs into your app. * This merges the new user with the existing user, if any exists, and will help prevent the creation of unnecessary/stale users. * Setting the Unique ID is a critical piece to tie a user across devices and installs/uninstalls as well across all platforms (i.e. iOS, Android, Windows, The Web). Set the **USER\_ATTRIBUTE\_UNIQUE\_ID** attribute as soon as the user is **logged in**. Unique ID can be something like an email ID, a username (unique), or a database ID or any Backend generated ID. * Do not set this for the user who not logged in. ## Login ```kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.setUniqueId(context, UNIQUE_ID) ``` ```java Java theme={null} MoEAnalyticsHelper.INSTANCE.setUniqueId(context, UNIQUE_ID); ``` **Note:** The following values are not allowed in the UniqueID field: "unknown", "guest", "null", "0", "1", "true", "false", "user\_attribute\_unique\_id", "(empty)", "na", "n/a", "", "dummy\_seller\_code", "user\_id", "id", "customer\_id", "uid", "userid", "none", "-2", "-1", "2" **UNIQUE ID chaos** * When you go live with MoEngage Android SDK for the first time, please ensure that you are setting the Unique ID of the already logged-in user along with other user attributes. * Kindly make sure that you are not using a single UNIQUE ID for all the users, this can happen if you hardcode the value, instead of fetching it from your servers. * If you pass 2 different UNIQUE ID information without calling the [logoutUser](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-e-core-helper/logout-user.html) method in between, the SDK will internally force the logout of the existing user. ## Logout The application needs to notify the MoEngage SDK whenever the user is logged out of the application. To notify the SDK, call the API whenever the user is logged out of the application. ```Kotlin Kotlin wrap theme={null} MoECoreHelper.logoutUser(context) ``` ```Java Java theme={null} MoECoreHelper.INSTANCE.logoutUser(context); ``` If the application is registering for a push token, it should pass the new push token to MoEngage SDK after the user logs out. For more information about passing push tokens, refer to [Push Configuration for Android SDK](/android-sdk/push/basic/push-configuration). ## Updating User Attribute Unique Id Use the method *setAlias()* to update the user attribute unique id instead of *setUniqueId()* with a different value. Using the method *setUniqueId()* with a new value creates unintended users in MoEngage. ```Kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.setAlias(ALIAS) ``` ```Java Java theme={null} MoEAnalyticsHelper.INSTANCE.setAlias(ALIAS); ``` # Track Events Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/basic/track-events Track custom user events and their attributes in your Android app using the MoEngage SDK. SDK adheres to the MoEngage FUP policies. For more information, refer to the [Fair Usage Policy](https://help.moengage.com/hc/en-us/articles/24151864954644-Fair-Usage-Policy-FUP#h_01HQSMZVQWT2KYP0PY1P8GQMRM). Tracking events is how you record any actions your users perform, along with any properties that describe the action. Every trackEvent call records a single user action. We recommend that you make your event names human-readable so that everyone on your team can know what they mean instantly. You can track an event using trackEvent with the event name and its characteristics (attributes/properties). Every event has 2 attributes, action name, and key, value pairs which represent additional information about the action. Add all the additional information which you think would be useful for segmentation while creating campaigns. For eg., the following code tracks a purchase event of a product. We are including attributes like amount, quantity, a category that describes the event we are tracking. ```Kotlin Kotlin wrap theme={null} val properties = Properties() properties // tracking integer .addAttribute("quantity", 2) // tracking string .addAttribute("product", "iPhone") // tracking date .addAttribute("purchaseDate", Date()) // tracking double .addAttribute("price", 5999.99) // tracking location .addAttribute("userLocation", GeoLocation(40.77, 73.98)) // tracking JSONArray .addAttribute("jsonArrayAttr", JSONArray(listOf(1, 2, 3))) // tracking JSONObject .addAttribute("jsonObjectAttr", JSONObject().put("name", "value")) MoEAnalyticsHelper.trackEvent(context, "Purchase", properties) ``` ```Java Java wrap theme={null} Properties properties = new Properties(); properties // tracking integer .addAttribute("quantity", 2) // tracking string .addAttribute("product", "iPhone") // tracking Date .addAttribute("purchaseDate", new Date()) // tracking double .addAttribute("price", 5999.99) // tracking location .addAttribute("userLocation", new Geolocation(40.77, 73.98)) // tracking JSONObject .addAttribute("jsonObjectAttr", new JSONObject()) // tracking JSONArray .addAttribute("jsonArrayAttr", new JSONArray()); MoEAnalyticsHelper.INSTANCE.trackEvent(context, "Purchase", properties); ``` context - context instance, change the name accordingly. Ensure that you are tracking event attributes without changing the data types. For example, in the purchase event, amount and quantity are tracked in numeric form. MoEngage detects the data type automatically unless you explicitly specify it as a String. MoEngage supports the following data types: String, Integer, Long, Double, Float, Boolean, Date, GeoLocation, JSON Object, and JSON Array. If any other data type is passed, MoEngage will reject the payload. The SDK by default tracks a certain set of commonly used events, make sure you use those events instead of tracking similar events again. Refer to the [documentation](https://help.moengage.com/hc/en-us/articles/360043067671-Default-Android-SDK-#Default-Events-Tracked:) to know more about the default events tracked by the SDK. Having unique timestamps for events is crucial to maintain accurate and reliable data. Please ensure that events do not share the same timestamp down to the millisecond level. # Analytics MoEngage SDK version 9.7.01 and later tracks user session and application traffic source. User session tracking provides the flexibility to selectively mark events as non-interactive. ## Non-interactive event Events that do not affect the session duration calculation in MoEngage Analytics are marked as Non-Interactive events. The following are considered non-interactive events: * Do not start a new session, even when the app is in the foreground * Do not extend the session * Do not have information on source and session An event is marked as non-interactive using the setNonIteractive() in the PayloadBuilder provided by the SDK to build event attributes. For example, ```Kotlin Kotlin wrap theme={null} val properties = Properties() properties.addAttribute("quantity", 2) .addAttribute("product", "iPhone") .addAttribute("purchaseDate", Date()) .addAttribute("price", 5999.99) .addAttribute("currency", "dollar") .addAttribute("jsonObjectAttr", JSONObject().put("name", "value")) .addAttribute("jsonArrayAttr", JSONArray(listOf(1, 2, 3))) .setNonInteractive() MoEAnalyticsHelper.trackEvent(context, "Purchase", properties) ``` ```Java Java wrap theme={null} Properties properties = new Properties(); properties.addAttribute("quantity", 2) .addAttribute("product", "iPhone") .addAttribute("purchaseDate", new Date()) .addAttribute("price", 5999.99) .addAttribute("currency", "dollar") .addAttribute("jsonObjectAttr", new JSONObject()) .addAttribute("jsonArrayAttr", new JSONArray()) .setNonInteractive(); MoEAnalyticsHelper.INSTANCE.trackEvent(context, "Purchase", properties); ``` For more information, refer to [MoEAnalyticsHelper#trackEvent](https://moengage.github.io/android-api-reference/core/com.moengage.core.analytics/\[android-jvm]-mo-e-analytics-helper/track-event.html) and [Properties](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-properties/index.html). # Track Custom Event for Exit Intent MoEngage SDK optionally notifies the application whenever the goes to the background. The application can track the custom event in this callback for exit intent. To get notified implement the [AppBackgroundListener](https://moengage.github.io/android-api-reference/core/com.moengage.core.listeners/-app-background-listener/index.html). Register the listener in the *onCreate()* of your Application class using *MoECallbacks.getInstance().addAppBackgroundListener()*. You can not use "moe\_" as a prefix while naming events, event attributes, or user attributes. It is a system prefix and using it might result in periodic blacklisting without prior communication. # Track Install or Update Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/basic/track-install-or-update Differentiate between app installs and updates in the MoEngage Android SDK using the setAppStatus API. SDK needs support to enable the update by the user application or install the application. You need to have a logic on the app side to distinguish between app *INSTALL* and *UPDATE* ```Kotlin Kotlin wrap theme={null} //For Fresh Install of App MoEAnalyticsHelper.setAppStatus(context, AppStatus.INSTALL) // For Existing user who has updated the app MoEAnalyticsHelper.setAppStatus(context, AppStatus.UPDATE) ``` ```Java Java theme={null} //For Fresh Install of App MoEAnalyticsHelper.INSTANCE.setAppStatus(context, AppStatus.INSTALL); // For Existing user who has updated the app MoEAnalyticsHelper.INSTANCE.setAppStatus(context, AppStatus.UPDATE); ``` If you uninstall and reinstall your app again, the SDK considers it as a fresh install. # Track User Attributes Source: https://moengage.com/docs/developer-guide/android-sdk/data-tracking/basic/track-user-attributes Track user attributes and set unique identifiers for user identification in the MoEngage Android SDK. User Attributes are pieces of information you know about a user. They could be demographics like age or gender, account-specific like plan, or whether a user has seen a particular A/B test variation. User attributes are a customer identity you can reference throughout the customer’s lifetime. # Identifying Users For SDK versions below 13.6.00 refer to [this document](/android-sdk/data-tracking/basic/setting-unique-id-for-sdk-versions-below-13-6-00). Setting identifiers is important to: * To tie user behavior across platforms, i.e., iOS, Android, Web, etc. * This is to ensure unnecessary or stale users are not created. * To identify users across installs/re-installs. ## Single Identifier Call the API below to pass the identifier on to the MoEngage SDK. ```kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.identifyUser(context, "identifier") ``` ```java Java theme={null} MoEAnalyticsHelper.INSTANCE.identifyUser(context, "identifier"); ``` *Note*: This method is a replacement for the deprecated ***setUniqueId()***. If you are using ***setUniqueId()*** in your application, consider replacing it with ***identifyUser()*** ## Multiple Identifiers If your application has multiple identifiers using which you identify a user you can pass all the identifiers to the SDK using the below API ```kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.identifyUser( context, mapOf("identifierName1" to "identifierValue1", "identifierName2" to "identifierValue2") ) ``` ```java Java theme={null} Map identifiers = new HashMap() {{ put("identifierName1", "identifierValue1"); put("identifierName2", "identifierValue2"); }}; MoEAnalyticsHelper.INSTANCE.identifyUser(context, identifiers); ``` **Updates to SDK functions for User Identification and Session Management** * **Forced Logout:** The MoEngage SDK no longer automatically logs out the previous user when a new user is detected on the device. Logout should now be explicitly called for workspaces enabled with Identity resolution to avoid data corruption. * **SetUniqueID:** `identifyUser` function supports multiple identifiers, which replaces the need of using `SetUniqueID` function for user identification. Note that `SetUniqueID` is marked for removal in the future releases of SDK versions - it is important to use `identifyUser` instead especially if you are using Identity resolution in your workspace. * **SetAlias:** For workspaces with the Identity resolution feature enabled, MoEngage SDK stores the previous identifier values. When `identifyUser` function is used to track the new identifier values, MoEngage SDK detects the change in identifier value and reports accordingly. If you call the `identifyUser` function without logging out, then the existing logged-in user's ID is updated. If you call `identifyUser()` multiple times with different identifier names, the SDK will append this identifier to the already set identifiers. Refer to our help [document](https://help.moengage.com/hc/en-us/articles/24050999467284-User-Identity-Management) to learn more about the feature. ## Logout The application needs to notify the MoEngage SDK whenever the user is logged out of the application. Call the API whenever the user is logged out of the application to notify the SDK. ```kotlin Kotlin wrap theme={null} MoECoreHelper.logoutUser(context) ``` ```java Java theme={null} MoECoreHelper.INSTANCE.logoutUser(context); ``` If the application is registering for a push token, it should pass the new push token to MoEngage SDK after the user logs out. For more information about passing push tokens, refer to [Push Configuration for Android SDK](/android-sdk/push/basic/push-configuration). # Tracking User Attributes The SDK provides APIs to track commonly tracked user attributes like First Name, Last Name, Email-Id, etc. Please use the provided methods for tracking these attributes. For more information on supported data types and data tracking policies, please refer to [Data Tracking Policies](https://help.moengage.com/hc/en-us/articles/360037314991#h_01H9QNZ61VNHSMFQC28MAZJXS9). ```kotlin Kotlin wrap theme={null} MoEAnalyticsHelper.setFirstName() MoEAnalyticsHelper.setLastName() MoEAnalyticsHelper.setUserName() MoEAnalyticsHelper.setLocation() MoEAnalyticsHelper.setGender() MoEAnalyticsHelper.setMobileNumber() MoEAnalyticsHelper.setBirthDate() MoEAnalyticsHelper.setEmailId() ``` ```java Java theme={null} MoEAnalyticsHelper.INSTANCE.setFirstName(); MoEAnalyticsHelper.INSTANCE.setLastName(); MoEAnalyticsHelper.INSTANCE.setUserName(); MoEAnalyticsHelper.INSTANCE.setLocation(); MoEAnalyticsHelper.INSTANCE.setGender(); MoEAnalyticsHelper.INSTANCE.setMobileNumber(); MoEAnalyticsHelper.INSTANCE.setBirthDate(); MoEAnalyticsHelper.INSTANCE.setEmailId(); ``` For setting other User Attributes, use the generic method **setUserAttribute(key, value).** Supported types for attribute value are `String`, `int`, `double`, `num`, `bool`, `List`, `List`, `List` & `List`. ```kotlin Kotlin wrap theme={null} // Tracking a String Attribute MoEAnalyticsHelper.setUserAttribute(context,"locality", "SF") // Tracking a Date Attribute MoEAnalyticsHelper.setUserAttribute(context,"signedUpOn", Date()) // Tracking a location attribute MoEAnalyticsHelper.setUserAttribute(context,"lastLocation", GeoLocation(40.77, 73.98)) // Tracking Array Attributes MoEAnalyticsHelper.setUserAttribute(context,"int_array",arrayOf(1,2,3)) MoEAnalyticsHelper.setUserAttribute(context,"string_array",arrayOf("English","French")) MoEAnalyticsHelper.setUserAttribute(context,"double_array",arrayOf(40.0,20.0)) MoEAnalyticsHelper.setUserAttribute(context,"json_array", JSONArray(listOf(1, 2, 3))) MoEAnalyticsHelper.setUserAttribute(context,"json_object", JSONObject().put("key", "value")) ``` ```java Java theme={null} // Tracking a String Attribute MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"locality", "SF"); // Tracking a Date Attribute MoEAnalyticsHelper.INSTANCE.setUserAttribute(context, "signedUpOn", new Date()); // Tracking a location attribute MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"lastLocation", new GeoLocation(40.77, 73.98)); // Tracking Array Attributes MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"int_array",new int[]{1,2,3}); MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"string_array",new String[]{"English","French"}); MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"double_array",new double[]{1.5,2.5}); MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"json_array", new JSONArray()); MoEAnalyticsHelper.INSTANCE.setUserAttribute(context,"json_object", new JSONObject()); ``` For more information about the detailed list of user attributes, refer to the [API reference](https://moengage.github.io/android-api-reference/core/com.moengage.core.analytics/\[android-jvm]-mo-e-analytics-helper/index.html). ## Reserved keywords for User Attributes Below is the list of keys that should not be used when tracking user attributes. * `USER_ATTRIBUTE_UNIQUE_ID` * `USER_ATTRIBUTE_USER_EMAIL` * `USER_ATTRIBUTE_USER_MOBILE` * `USER_ATTRIBUTE_USER_NAME` * `USER_ATTRIBUTE_USER_GENDER` * `USER_ATTRIBUTE_USER_FIRST_NAME` * `USER_ATTRIBUTE_USER_LAST_NAME` * `USER_ATTRIBUTE_USER_BDAY` * `USER_ATTRIBUTE_NOTIFICATION_PREF` * `USER_ATTRIBUTE_OLD_ID` * `MOE_TIME_FORMAT` * `MOE_TIME_TIMEZONE` * `USER_ATTRIBUTE_DND_START_TIME` * `USER_ATTRIBUTE_DND_END_TIME` * `MOE_GAID` * `INSTALL` * `UPDATE` * `MOE_ISLAT` * `status` * `user_id` You cannot use "moe\_" as a prefix while naming events, event attributes, or user attributes. It is a system prefix and using it might result in periodic blacklisting without prior communication. # In-App NATIV Source: https://moengage.com/docs/developer-guide/android-sdk/in-app-messages/in-app-nativ Display contextual in-app messages to your Android app users using the MoEngage In-App NATIV SDK. In-App NATIV Campaigns target your users by showing a message while the user is using your app. They are very effective in providing contextual information and help to cross-sell/up-sell on desired screens of your app or/and on desired actions performed by the user in your app. Latest Popupimage # SDK Installation ## Installing using BOM Integration using BOM is the recommended way of integration; refer to the [Install Using BOM](/developer-guide/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:inapp") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. ### **Requirements for displaying images and GIFs in InApp** Starting InApp version **7.0.0,** SDK requires [Glide](https://bumptech.github.io/glide/) to show images and GIFs in the in-apps. You need to add the below dependency in your **build.gradle** file. ```groovy Groovy wrap theme={null} dependencies { ... implementation("com.github.bumptech.glide:glide:4.16.0") } ``` # Display InApp MoEngage can not show the InApp by default, and the app should call the following method in the places where necessary to show the InApps to the user. We recommend adding this method in onStart() of your activity or onResume() of your fragment. [MoEInAppHelper.getInstance().showInApp(context)](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/show-in-app.html)  ```Kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().showInApp(context) ``` # Display Nudges Starting with version \*\*7.0.0,\*\*MoEngage InApp SDK supports displaying Non-Intrusive nudges.  MoEngage can not show the Nudges by default, and the app should call the following method in the places where necessary to show the Nudges to the user. We would recommend you add this method in onStart() of your activity or onResume() of your fragment. [MoEInAppHelper.getInstance().showNudge(context)](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/show-nudge.html) ```Kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().showNudge(context) ``` # Handling Configuration change Starting SDK version **11.4.00,** in-apps are supported in both portrait and landscape modes. SDK internally handles in-app display on orientation change when the activity restart is handled by the system. In case your activity is handling the configuration change by itself, you have to notify the SDK by invoking [*MoEInAppHelper.getInstance().onConfigurationChanged()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/on-configuration-changed.html) API for SDK to redraw the in-app when the activity receives *onConfigurationChanged()* callback from the framework. ```kotlin Kotlin wrap theme={null} override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) MoEInAppHelper.getInstance().onConfigurationChanged() } ``` ```java Java theme={null} @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); MoEInAppHelper.getInstance().onConfigurationChanged(); } ``` # Contextual InApp You can restrict the in-apps based on the user's context in the application, apart from restricting InApp campaigns on a specific screen/activity. To set the user's context in the application, use [*setInAppContext()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/set-in-app-context.html) API, as shown below. ## Set Context Call the below method in the *onStart()* of your *Activity* or *Fragment* before calling *showInApp().* ```kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().setInAppContext(setOf("context1", "context2", "context3")) ``` ```java Java theme={null} Set inAppContext = new HashSet<>(); inAppContext.add("context1"); inAppContext.add("context2"); inAppContext.add("context3"); MoEInAppHelper.getInstance().setInAppContext(inAppContext); ``` The context is not the same context as [Android Context](https://developer.android.com/reference/android/content/Context?hl=en).  This user's context in the application flow. ## Reset Context Once the user is moving out of the context, use the [*restInAppContext()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/reset-in-app-context.html) API to reset/clear the existing context. ```kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().resetInAppContext() ``` ```java Java theme={null} MoEInAppHelper.getInstance().resetInAppContext(); ``` Code example below: ```kotlin Kotlin wrap theme={null} // Activity class MyCustomActivity: Activity() { override fun onStart() { super.onStart() MoEInAppHelper.getInstance().setInAppContext(setOf("context1", "context2")) MoEInAppHelper.getInstance().showInApp(this) } override fun onStop() { super.onStop() MoEInAppHelper.getInstance().resetInAppContext() } } // Fragment class MyCustomFragment: Fragment() { override fun onStart() { super.onStart() // Fragment's onStart code // context1 and context2 can be changes as per screen/requirement MoEInAppHelper.getInstance().setInAppContext(setOf("context1", "context2")) MoEInAppHelper.getInstance().showInApp(this) } override fun onStop() { super.onStop() // Fragment's onStop code MoEInAppHelper.getInstance().resetInAppContext() } } ``` ```java Java theme={null} // Activity public class MyCustomActivity extends Activity { @Override protected void onStart() { super.onStart(); // Activity's custom onStart logic here Set inAppContext = new HashSet<>(); inAppContext.add("context1"); // Change the string name as per your requirement inAppContext.add("context2"); // Change the string name as per your requirement MoEInAppHelper.getInstance().setInAppContext(inAppContext); MoEInAppHelper.getInstance().showInApp(this) } @Override protected void onStop() { super.onStop(); // Activity's custom onStop logic here MoEInAppHelper.getInstance().resetInAppContext(); } } // Fragment public class MyCustomFragment extends Fragment { // Other Fragment code @Override public void onStart() { super.onStart(); // Fragment's onStart code here Set inAppContext = new HashSet<>(); inAppContext.add("context1"); inAppContext.add("context2"); MoEInAppHelper.getInstance().setInAppContext(inAppContext); MoEInAppHelper.getInstance().showInApp(this) } @Override public void onStop() { super.onStop(); MoEInAppHelper.getInstance().resetInAppContext(); } } ``` # WebView Customization Starting with In-App SDK version **9.6.0**, the SDK supports customizing the underlying WebView used to render HTML In-App messages. This allows for modifying the WebView settings, adding custom JavaScript interfaces, and implementing other configurations to the WebView used to render HTML In-Apps. To customize the WebView, you must invoke the `MoEInAppHelper.getInstance().setInAppWebViewCustomizer()` API. Any custom settings defined using this API will override the default MoEngage In-App WebView settings. ```kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().setInAppWebViewCustomizer {     addJavascriptInterface(MyBridge(), "bridge")     settings.mediaPlaybackRequiresUserGesture = false } ``` ```java Java theme={null} MoEInAppHelper.getInstance().setInAppWebViewCustomizer( new kotlin.jvm.functions.Function1() { @Override public kotlin.Unit invoke(InAppWebView webView) { WebSettings settings = webView.getSettings(); settings.setMediaPlaybackRequiresUserGesture(false); webView.addJavascriptInterface(new CustomJavaScriptBridge(), "myBridge"); return kotlin.Unit.INSTANCE; } } ); ``` # Self-Handled InApps Self-handled In-Apps are messages that the SDK delivers to the application, and the application builds the UI using the SDK's delivered payload. ## Single Self-Handled InApps To get the self-handled in-app, use the below API. ```kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().getSelfHandledInApp(context, listener) ``` ```java Java theme={null} MoEInAppHelper.getInstance().getSelfHandledInApp(context, listener); ``` The **listener** is an instance of [*SelfHandledAvailableListener.*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-available-listener/index.html) This method should be called in the *onResume()* of your Fragment or *onStart()* of your activity.\ The above method is asynchronous and does not return the payload immediately, once the payload is available [*onSelfHandledAvailable(), the listener callback*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-available-listener/on-self-handled-available.html) would be called with the payload. ### Event-Triggered Self Handled InApps To get a callback for an event triggered, implement *SelfHandledAvailableListener* and register for a listener using [*MoEInAppHelper.getInstance().setSelfHandledListener()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/set-self-handled-listener.html). SDK will notify the registered listener once the campaign is available. We recommend registering this listener in the *onCreate()* of the *Application* class if the trigger event can happen on multiple screens. ## Multiple Self-Handled InApps * This feature requires a minimum catalog version **4.5.0** * Event-triggered multiple self-handled inapps are not supported. Fetch Multiple Self Handled Campaigns using [*getSelfHandledInApps()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/index.html#1129437895%2FFunctions%2F434681417). The MoEngage SDK will return up to 5 campaigns(in the order of campaign priority set at the time of campaign creation) in the campaigns available callback method [*onCampaignsAvailable()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-campaigns-available-listener/index.html#-1056690682%2FFunctions%2F434681417)**.** ```kotlin Kotlin wrap theme={null} MoEInAppHelper.getInstance().getSelfHandledInApps(context, listener) ``` ```java Java theme={null} MoEInAppHelper.getInstance().getSelfHandledInApps(context, listener); ``` The *listener* is an instance of [*SelfHandledCampaignsAvailableListener*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-campaigns-available-listener/index.html)[.](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-available-listener/index.html) This method should be called in the *onResume()* of your Fragment or *onStart()* of your activity.\ The above method is asynchronous and does not return the payload immediately, once the payload is available [*onCampaignsAvailable() callback*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-campaigns-available-listener/index.html#-1056690682%2FFunctions%2F434681417) of the listener would be called with the payload. ### Tracking Statistics for Multiple Self-Handled In-Apps The *onCampaignsAvailable()* callback method returns [*SelfHandledCampaignsData*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.model/-self-handled-campaigns-data/index.html), which contains a list of [*SelfHandledCampaignData*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.model/-self-handled-campaign-data/index.html) objects. The statistics for each *SelfHandledCampaignData* object must be tracked individually below APIs. ### Fetching Contextual Multiple Self-Handled InApps To fetch contextual multiple self-handled inapps, set the inapp contexts using [*setInAppContext()*](/developer-guide/android-sdk/in-app-messages/in-app-nativ#Set-Context) before calling \*[getSelfHandledInApps()](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/index.html#1129437895%2FFunctions%2F434681417).\*This will return a list of contextual and non-contextual inapps(in the order of campaign priority set at the time of campaign creation). ### Campaign Selection Logic * **Default Limit**: By default, only 5 campaigns will be fetched. * **Priority-Based Selection**: Campaigns are delivered based on their priority and last updated time. It checks for priority first and then checks the last updated time on conflicting priorities * **Exclusion criteria**: Campaigns are only excluded based on specific rules like frequency capping, eligibility criteria, campaign status, or priority limits. **Example Scenario:** If you have 6 campaigns with different priorities, published time and contexts: * Context 1: Campaign 1 (P0, T2), Campaign 2 (P1, T3), Campaign 3 (P2, T6) * Context 2: Campaign 4 (P0, T1), Campaign 5 (P1, T5) * Context 3: Campaign 6 (P0, T4) Following campaigns will be delivered in this order: \[Campaign 4, Campaign 1, Campaign 6, Campaign 2, Campaign 5] **Selection Algorithm:** 1. Filter campaigns by user eligibility and targeting criteria 2. Sort by campaign priority (P0, P1, P2, etc.) 3. For campaigns with same priority, sort by most recent update timestamp 4. Return top 5 campaigns #### **Best Practices for Campaign Organization for multiple self handled campaigns** For optimal performance across multiple contexts on a single page, organize your campaigns like this: * Context 1 (Homepage): Campaign A (P0), Campaign B (P1) * Context 2 (Product): Campaign C (P0), Campaign D (P1) * Context 3 (Checkout): Campaign E (P0) This ensures each context has relevant campaigns without hitting the 5-campaign limit.  Also, make sure that you set the priority of the campaigns you want to fetch accordingly, because the method will fetch all self-handled campaigns regardless of whether they are context-based or not. ## Tracking Statistics for Self-Handled In-Apps The application must notify MoEngage SDK whenever the In-App messages are displayed, clicked on, or dismissed, as the application controls these actions. The following methods are called to notify the SDK. The data object [*SelfHandledCampaignData*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.model/-self-handled-campaign-data/index.html) provided to the application in the callback for self-handled in-app should be passed as a parameter to the following APIs. ```kotlin Kotlin wrap theme={null} // call whenever in-app is shown MoEInAppHelper.getInstance().selfHandledShown(context, data) // call whenever in-app is clicked MoEInAppHelper.getInstance().selfHandledClicked(context, data) // call whenever in-app is dismissed MoEInAppHelper.getInstance().selfHandledDismissed(context, data) ``` ```java Java theme={null} // call whenever in-app is shown MoEInAppHelper.getInstance().selfHandledShown(context, data); // call whenever in-app is clicked MoEInAppHelper.getInstance().selfHandledClicked(context, data); // call whenever in-app is dismissed MoEInAppHelper.getInstance().selfHandledDismissed(context, data); ``` For more information, refer to the [API documentation](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/index.html#-59857046%2FFunctions%2F434681417). # In-Apps Callback ## Lifecycle callback To get callbacks whenever an InApp campaign is shown or dismissed, implement the [*InAppLifeCycleListener*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-in-app-life-cycle-listener/index.html) and register for the callbacks using [*MoEInAppHelper.getInstance().addInAppLifeCycleListener()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/add-in-app-life-cycle-listener.html). ## Click Callback To handle user navigation or custom action, SDK provides a callback whenever an in-app widget is clicked with either Navigation or Custom action. To get callbacks implement the [*OnClickActionListener*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-on-click-action-listener/index.html) interface and register for the callbacks using [*MoEInAppHelper.getInstance().setClickActionListener()*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp/-mo-e-in-app-helper/set-click-action-listener.html). # Blocking InApps on Screens Additionally, you can block in-app on a specific screen or handle the status bar visibility using the [InAppConfig](https://moengage.github.io/android-api-reference/core/com.moengage.core.config/\[android-jvm]-in-app-config/index.html) object and pass it to the SDK using the [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) object. Use the [configureInApps()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-in-apps.html) API to pass on the configuration to the SDK. ```kotlin Kotlin wrap theme={null} // List of activity classes on which in-app should not be shown val inAppOptOut = mutableListOf() inAppOptOut.add(SplashActivity::class.java.name) val moengage = MoEngage.Builder(application, "XXXXXXXX") .configureInApps(InAppConfig(inAppOptOut,true)) .build() MoEngage.initialise(moengage) ``` ```java Java theme={null} ArrayList inAppOptOut = new ArrayList<>(); inAppOptOut.add(SplashActivity.class.getName()); MoEngage.Builder builder = new MoEngage.Builder(application, "XXXXXXXXXX") .configureInApps(new InAppConfig(inAppOptOut,true)); MoEngage.initialise(builder.build()); ``` # Testing In-App Refer to this [link](https://help.moengage.com/hc/en-us/articles/360047789092-Testing-your-In-App-Nativ-Campaigns) to read more about how to create and test in-apps. # Implementing Embedded Nudges (Deprecated) Starting InApp version **7.0.0,** embedded nudges are no longer supported. Nudges are non-disruptive messages which can be placed anywhere in the activity. Latest Nudgeimage Add the following code in the activity/fragment layout file. ```XML XML wrap theme={null} ``` ## Using in an Activity Get an instance of the nudge view in the **onCreate()** and initialize the nudge view in the **onStart()** of the Activity. ## Using in a Fragment Get an instance of the nudge view in the **onCreateView()** and initialize the nudge view in the **onResume()** of the fragment. Use the below code to get the instance of the ***NudgeView*** and initialize it. ```kotlin Kotlin wrap theme={null} // get instance of the view val nudge = findViewById(R.id.nudge) // initialize nudge.initialiseNudgeView(activity) ``` ```java Java theme={null} // get instance of the view NudgeView nv = (NudgeView)findViewById(R.id.nudge); // initialize nv.initialiseNudgeView(getActivity()); ``` # FAQs * For In-App SDK version 9.6.0 and above, refer to the [WebView Customization](https://developers.moengage.com/hc/en-us/articles/4403652537492-In-App-NATIV#h_01KC43AKSVZHQDM57VMX0K35PF). * If you are using In-App SDK version below 9.6.0, perform the following steps: * Android's default WebView does not support file inputs. To enable this functionality, trigger a Custom Action from your HTML and handle it natively with an *OnClickActionListener*.\ Within the listener, launch your native file picker or camera logic. Ensure your app requests the required runtime permissions, such as CAMERA and READ\_EXTERNAL\_STORAGE. HTMLGUYS Example: ```kotlin Kotlin wrap theme={null} val listener = OnClickActionListener { clickData -> if (clickData.action.actionType == ActionType.CUSTOM_ACTION && (clickData.action as CustomAction).keyValuePairs["action"] == "uploadPhoto") { openImageChooser() // Your native camera/gallery function true // Indicates the action was handled } else { false } } ``` * For iOS, file inputs work by default. However, for a consistent cross-platform implementation, we recommend using the same Custom Action approach. # Migrating from addon-inbox 6.0.2 Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migrating-from-addon-inbox-602 Migrate from addon-inbox 6.0.2 to the updated inbox-core and inbox-ui modules in MoEngage Android SDK. This migration is required only if you are using *addon-inbox 6.0.2* or below and migrating to *11.2.00* or above version of moe-android-sdk. Since the early days of MoEngage, we have provided `addon-inbox` artifact for using Notification Center in your application. We have revamped the module and broken down the module into multiple modules to make it more robust, lightweight, and scalable for future improvements/enhancements. # Updated Artifacts `inbox-core` - Module contains APIs and helper methods to build an inbox. Provides APIs to fetch messages, track clicks, etc `inbox-ui` - Module contains the user interface for the inbox module and helper methods for customization of the UI. # Using SDK Notification Center If you are using the UI provided by the SDK you need to include the `inbox-ui` module in your application. Key changes you would notice here apart from the artifact name update * RecyclerView used instead of ListView * Updated UI * API updates for customizing the UI Refer to the updated [MoEngage's default Notification Center](https://developers.moengage.com/hc/en-us/articles/4403878923284) for details on how to use the default UI and possible customization. # Self handled Notification Center If you were building your own Notification Center consuming the data from MoEngage we have made the APIs simpler for you and made the SDK lighter. Integrate the `inbox-core` module. Refer to the [Self Handled Notification Center](https://developers.moengage.com/hc/en-us/articles/4403878923284-Notification-Center-for-MoEngage-SDK-Version-11-2-00-or-later#self-handled-notification-center-0-9) for updated APIs # Update the packages: While we have revamped the modules we have tried to maintain some of the classes to avoid re-integration wherever feasible. Though we have not changed the APIs as such we have moved it to a new package for better integration in the future.\ Refer to the below table for updated packages. | Then | Now | | -------------------------------------------------------------- | --------------------------------------------------------------- | | com.moengage.addon.inbox.MoEInboxHelper | com.moengage.inbox.core.MoEInboxHelper | | com.moengage.addon.inbox.listener. OnMessagesAvailableListener | com.moengage.inbox.core.listener. OnMessagesAvailableListener | | com.moengage.addon.inbox. InboxMessageClickCallback | com.moengage.inbox.ui.listener. OnMessageClickListener | | com.moengage.addon.inbox.MoEInboxActivity | com.moengage.inbox.ui.view\.InboxActivity | | com.moengage.addon.inbox.InboxFragment | com.moengage.inbox.ui.view\.InboxFragment | | com.moengage.addon.inbox.InboxManager .ViewHolder | com.moengage.inbox.ui.adapter.ViewHolder | | com.moengage.addon.inbox.InboxManager .InboxAdapter | com.moengage.inbox.ui.adapter.InboxAdapter | # Migrating from GCM to FCM Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migrating-from-gcm-to-fcm Migrate your Android app from Google Cloud Messaging to Firebase Cloud Messaging for MoEngage push. As of April 10, 2018, Google has deprecated GCM. The GCM server and client APIs are deprecated and will be removed as soon as April 11, 2019. Migrate GCM apps to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features. # Migrate the GCM Client library to FCM Client Library ## Import your GCM project as a Firebase project 1. In the Firebase console, select Add Project. 2. Select your GCM project from the list of existing Google Cloud projects, and select Add Firebase. 3. In the Firebase welcome screen, select Add Firebase to your Android App. 4. Provide your package name and SHA-1, and select Add App. A new google-services.json file for your Firebase app is downloaded. 5. Select Continue and follow the detailed instructions for adding the Google Services plugin in Android Studio. ## Switch to FCM in the app-level build.gradle Add the latest version of the Firebase SDK. ```Groovy Groovy wrap theme={null} dependencies { compile "com.google.firebase:firebase-messaging:15.0.0" } ``` ## Edit your app's manifest If you have the below declaration in your Manifest remove it. ```XML XML wrap theme={null} ... ``` Refer to the [official migration guide](https://developers.google.com/cloud-messaging/android/android-migrate-fcm) for more details. # Migrate MoEngage library from GCM to FCM The [latest version](/developer-guide/release-notes/android-sdk/2023-and-older-1) of the MoEngage SDK ships with the Firebase dependency. ## Using SDK version 8.x.x or above If you are using SDK version 8.0.00 or above, then you are already using the FCM library of MoEngage, provided you have not removed it as mentioned below. ```Groovy Groovy wrap theme={null} compile ('com.moengage:moe-android-sdk:8.5.00'){ exclude group: 'com.moengage', module: 'moe-push-firebase' } compile 'com.moengage:moe-push-gcm:2.0.04' ``` If you are using something like the above change it as below ```Groovy Groovy wrap theme={null} dependencies { compile 'com.moengage:moe-android-sdk:8.5.00' } ``` # Using SDK version 7.x.x MoEngage SDK version 7.x.x uses the GCM library by default. To use the FCM library, you need to exclude the GCM library and add the FCM library as mentioned below. ```Groovy Groovy wrap theme={null} dependencies { compile ('com.moengage:moe-android-sdk:7.7.16'){ exclude group: 'com.moengage', module: 'moe-push-gcm' } compile 'com.moengage:moe-push-firebase:1.1.02' } ``` # Migrating to Push Amp+ 2.0.00 Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migrating-to-push-amp-plus-2000 Migrate the MoEngage Push Amp+ SDK from version 1.2.00 or below to 2.x with updated configuration. These migration steps are only required if you are updating the push-amp-plus SDK from 1.2.00 or below to 2.x or higher. In the advent of making our SDK more configurable and robust, we have some changes or improvements in the SDK. We had to make some breaking changes in the SDK in the process. We request you to refer to the migration steps below and make changes accordingly.  # Update the SDK Version Update the SDK to the latest version by updating the dependency versions in your `app/build.gradle` file. You would need to update the version for `moe-android-sdk` `push-amp-plus` artifacts.\ Ensure refer to the [Release Notes](https://developers.moengage.com/hc/en-us/articles/4403896795540). **Version Compatibility** The *push-amp-plus* artifact should be compatible with the *moe-android-sdk* artifact you have already added. Make sure you check the [version compatibility](https://developers.moengage.com/hc/en-us/articles/4403458168468) and pick the right version for your application # Configure Push Amp+ To configure Push Amp plus follow these steps as described in [Push AMP Plus Integration](https://developers.moengage.com/hc/en-us/articles/4403458168468): 1. Add Permissions to the Manifest File 2. Add Receiver and Services in Manifest File 3. Add Meta Data 4. Configuring Receviers If you are unsure how to get the metadata required for the configuration or don't know where to find it, contact your Account Manager or the MoEngage Support team. # Migration from 4.x to 5.x (One time activity) Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migration-from-4x-to-5x-one-time-activity Migrate your MoEngage Android SDK integration from version 4.x to 5.x with updated receivers and APIs. Follow the installation steps mentioned [here](https://developers.moengage.com/hc/en-us/articles/44622788607892). Changes required to migrate to 5.x are minimum but some structural changes require you to remove some lines of code. This had to be done to make it loosely coupled and easy to integrate * No change in Manifest permissions * Basic integration points remain same * Changes in receivers & services * Deprecated few APIs and provided alternatives * Inbox moved out of Main SDK and added to add-on lib If using Play Services 7.3 **No Changes in the following receivers**. ```XML XML wrap theme={null} {/* MOENGAGE RECEIVER FOR RECEIVING GCM BROADCAST MESSAGES */} {/* MOENGAGE RECEIVER FOR RECEIVING INSTALLATION INTENT */} ``` If using Google Play Services 7.5 ```XML XML wrap theme={null} ``` # Remove the following receivers ```Java Java wrap theme={null} {/* MOENGAGE RECEIVER FOR RECEIVING PACKAGE UPDATED INTENT */} {/* MOENGAGE SERVICE PROCESSING GCM MESSAGES */} {/* MOENGAGE RECEIVER FOR INTERNAL PURPOSE */} {/* MOENGAGE RECEIVER FOR TRIGGERING INTERACTION DATA SYNC */} ``` # Add the following Receivers ```XML XML wrap theme={null} ``` # Add the following Provider ```XML XML wrap theme={null} ``` # Add the \ following tags ```XML XML wrap theme={null} {/* MANDATORY FIELD: APP ID AS SEEN ON MOENGAGE DASHBOARD APP SETTINGS PAGE */} {/* MANDATORY FIELD: SENDER ID , i.e. THE PROJECT NUMBER AS MENTIONED ON GOOGLE CLOUD CONSOLE PROJECTS PAGE */} {/* MANDATORY FIELD: THE NOTIFICATION SMALL ICON WHICH WILL BE USED TO SET TO NOTIFICATIONS POSTED */} {/* MANDATORY FIELD: THE NOTIFICATION LARGE ICON WHICH WILL BE USED TO SET TO NOTIFICATIONS POSTED */} {/* OPTIONAL FIELD: THE NOTIFICATION TYPE WHICH WILL BE USED, SINGLE OR MULTIPLE. DEFAULT BEHAVIOR IS SINGLE */} {/* OPTIONAL FIELD: THE NOTIFICATION TONE THAT WILL BE USED. IF NOT SET WILL PLAY THE DEFAULT SOUND */} ``` # Delete the following code ```Java Java wrap theme={null} //Delete the INITIALISATION METHOD CALL. THIS IS DEPRECATED AND NOT REQUIRED ANY LONGER helper.initialize( GCM_SENDER_ID, MOE_APP_ID); //Delete the REGISTER METHOD CALL. THIS IS DEPRECATED AND NOT REQUIRED ANY LONGER helper.Register(R.drawable.ic_launcher); ``` # Add the following code (optional) Add this only if you support the change in orientation. ```Java Java wrap theme={null} /* * (non-Javadoc) * * @see android.app.Activity#onSaveInstanceState(android.os.Bundle) */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mHelper.onSaveInstanceState(outState); } /* * (non-Javadoc) * * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle) */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mHelper.onRestoreInstanceState(savedInstanceState); } ``` # Inbox Users Change the following: Old declaration ```XML XML wrap theme={null} {/* MOENGAGE INBOX ACTIVITY DECLARATION */} ``` Change to ```XML XML wrap theme={null} ``` # Add the Install/Update Differentiator Add the install update differentiator as mentioned [here](https://developers.moengage.com/hc/en-us/articles/4402050819220). In case you have any issues, please do contact the Custom Success Managers who will help you out # Migration to 10.x.xx Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migration-to-10xxx Migrate to MoEngage Android SDK 10.x.xx with updated APIs, removed GCM support, and behavioral changes. # Migrating from Manifest based integration In version SDK version `9.0.00` we introduced a new way of integrating the MoEngage SDK via Java/Kotlin code and deprecated integration using metadata in the Manifest file. Starting version `10.0.00` we are removing support for integration which uses Manifest metadata. Refer to the [documentation](https://developers.moengage.com/hc/en-us/articles/4403898171156) to learn more on the migration to code-based integration. # Behavioral Changes * Self-Handled in-app delivered on the Main thread * Removed support for GCM * Removed support for Baidu * For showing gifs in in-apps SDK was dependent on Fresco before SDK version `10.0.00` Starting from SDK version `10.0.00` SDK uses Glide to show gifs. Make sure you add Glide as a dependency in your application if you wish to use gifs. * "nav\_provier", "nav\_source", will no longer be present in the push payload or deep-link link URL. * If sender id is provided for while initializing the SDK it will be used for token registration instead of the default sender id in the `google-services.json` file. * InApp Callbacks - InApp Callbacks listener is now a concrete class rather than an interface. * InstallReceiver removed from the SDK. If you have added `com.moe.pushlibrary.InstallReceiver` in the manifest please remove. # Update removed APIs In version `10.0.00` of the SDK, we have removed many of the APIs which were long deprecated. If you are still using the deprecated APIs you have to update to the new APIs. Below is a table mapping the equivalents of the removed APIs. Some of the APIs might not have an alternate API as the functionality might have been handled internally or no longer supported. | Then | Now | | ---------------------------------------------------------------- | --------------------------------------------------------------- | | MoEngage.Builder#setTrackingOptOut(List) | MoEngage.Builder#optOutActivityTracking(List) | | MoEngage.Builder#setInAppOptOut(List) | MoEngage.Builder#optOutInAppFromActivity (List) | | MoEHelper#setFlushInterval(long) | MoEngage.Builder#setFlushInterval(long) | | MoEHelper#setExistingUser(boolean) | MoEHelper#setAppStatus(AppStatus) | | MoEHelper#optOutOfAdIdCollection (Context, boolean) | MoEngage.Builder#optOutGAIDCollection() | | MoEHelper#optOutOfLocationTracking (Context, boolean) | MoEngage.Builder#optOutLocationTracking() | | MoEHelper#optOutOfGeoFences (Context, boolean) | MoEngage.Builder#optOutGeoFence() | | MoEHelper#setLogLevel(int) | MoEngage.Builder#setLogLevel(int) | | MoEHelper#setLogStatus(boolean) | MoEngage.Builder#enableLogsForSignedBuild() | | MoEHelper#optOutOfAndroidIdCollection(Context, boolean) | MoEngage.Builder#optOutAndroidIdCollection() | | MoEHelper#optOutOfOperatorNameCollection (Context, boolean) | MoEngage.Builder#optOutCarrier NameCollection() | | MoEHelper#optOutOfDeviceAttributeCollection (Context, boolean) | MoEngage.Builder#optOutDevice AttributeCollection() | | MoEHelper#redirectDataToRegion(int) | MoEngage.Builder#redirectDataToRegion (MoEngage.DATA\_REGION) | | MoEHelper#setPeriodicFlushState(boolean) | MoEngage.Builder#optOutPeriodicFlush() | | PushManager#optoutBackStackBuilder(Boolean) | MoEngage.Builder#optOutBackStackBuilder() | | MoEPushCallBacks.OnMoEPushReceiveListener | PushMessageListener#onNotificationReceived() | | MoEPushCallBacks.OnMoEPushNavigationAction | PushMessageListener#onHandleRedirection() | | MoEPushCallbacks.OnMoEPushClickListener | PushMessageListener#onHandleRedirection() | | MoEPushCallBacks.OnMoEPushClearedListener | PushMessageListener#onNotificationCleared() | | MoEPushCallBacks#setOnMoEPushReceiveListener | MoEPushHelper#setMessageListener\|(PushMessageListener) | | MoEPushCallBacks#setOnMoEPush NavigationAction | MoEPushHelper#setMessageListener( PushMessageListener) | | MoEPushCallBacks#setOnMoEPush ClearedListener | MoEPushHelper#setMessageListener (PushMessageListener) | | MoEHelper#setBirthDate(String) | MoEHelper#setBirthDate(Date) | | PushManager#optOutMoEngageExtras(boolean) | Not required any more | | MoEHelper#showInAppIfAny(boolean) | Not required any more | | MoEHelper#autoIntegrate(Application) | Not required any more | | MoEHelper#onStart(Activity) | Not required any more | | MoEHelper#onStop(Activity) | Not required any more | | MoEHelper#onResume(Activity) | Not required any more | | MoEHelper#onFragmentStart(Activity, String) | Not required any more | | MoEHelper#onFragmentStop(Activity, String) | Not required any more | | MoEHelper#optOutOfIMEICollection (Context, boolean) | Not required any more | | MoEngage.Builder#optOutMoEngageExtras() | Not required any more | | MoEngage.Builder#enableInstantApp() | Merged with MoEngage.Builder#setSenderId() | | MoEngage.Builder#enableBaiduPush(String) | Baidu Push not supported. | # APIs deprecated in 10.0.00 In version `10.0.00` we have deprecated a few APIs to improve performance and better support in the future. Below is the list of deprecated APIs and their alternatives, please update to the latest methods. | Then | Now | | ----------------------------------------- | ----------------------------------------------------- | | MoEngage.Builder#setNotificationType(int) | MoEngage.Builder#enableMultipleNotificationInDrawer() | | PayloadBuilder | Properties | # Migration To Maven Central Source: https://moengage.com/docs/developer-guide/android-sdk/migration/migration-to-maven-central Migrate your MoEngage Android SDK dependencies from JCenter to Maven Central. JFrog recently announced that they are making important changes that will impact users of Bintray, JCenter. We as developers would not be able to publish new packages on Bintray after 31st March 2021 and existing packages wouldn't be available for use after 1st February 2022.\ Checkout out the [blog post](https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/) for more details. We at MoEngage have been publishing our Android SDK/artifacts to Jcenter for the past few years and have moved to publish artifacts to Maven Central. Going forward all the artifacts would be available via Maven Central only. # How does it affect you? Since existing packages are available for download till 1st February 2022 the shutdown will not affect you immediately. Though we strongly recommend you migrate to the version published on maven central(`11.0.04` or above) at the earliest to avoid any issues. The versions mentioned are the latest version at the time of publishing this document(1st March 2021). Refer to the Release Notes of the respective framework. # Migration for 11.x.xx If you are using the 11.x.xx version of the MoEngage SDK you would just need to change the version to `11.0.04` or above to move to maven central Artifacts.\ Make sure you update the other unbundled/dependent MoEngage SDKs or modules(like Push Amp Plus, Push Templates, etc.) to the compatible version.\ Below is the list of compatible versions for `11.0.04`, 1st version on maven central. | Artifact | Version | | ----------------- | ------- | | moe-android-sdk | 11.0.04 | | addon-inbox | 6.0.2 | | cards | 2.0.02 | | hms-pushkit | 2.0.02 | | push-amp-plus | 3.0.02 | | rich-notification | 2.0.03 | | geofence | 1.0.02 | # Migration for 10.x.xx Update to the latest SDK version `11.0.04` or above. Since it would be a major version update there might be additional code changes required apart from changing the version number in your gradle file(s). Refer to the [Updating to 11.x.xx](/developer-guide/android-sdk/migration/updating-to-11xxx-from-10xxx) document and [Release Notes](/developer-guide/release-notes/android-sdk/2023-and-older-1) for more details.\ Make sure you update the other unbundled/dependent MoEngage SDKs or modules(like Push Amp Plus, Push Templates, etc.) to the compatible version. In case, you are not able to update to `11.x.xx` due to some technical limitations or bandwidth issues we have uploaded the last `10.x.xx` version along with the add-on modules on Maven Central. You can update to the below versions. | Artifact | Version | | ----------------- | ------- | | moe-android-sdk | 10.6.01 | | addon-inbox | 5.3.1 | | cards | 1.2.01 | | hms-pushkit | 1.2.01 | | push-amp-plus | 2.2.01 | | rich-notification | 1.2.02 | We strongly recommend you update to the latest version instead of 10.6.01 to take advantage of all the latest features/improvements/optimizations we have made. # Migration for below 10.x.xx We recommend you update to the latest version, we will not be publishing/moving 9.x.xx or below to maven central. Since you would be updating 2 major versions we recommend you go through the documentation and update accordingly. # Cross-Platform Frameworks MoEngage provides support for a number of cross-platform frameworks like React-Native, Flutter, Unity, Cordova, etc. Our Cross-Platform frameworks are dependent on the above-mentioned native(Java/Kotlin) Android SDK and equally affected by the Jcenter shutdown. We have updated our Cross-Platform plugins or packages to use artifacts published on Maven Central instead of Jcenter.\ Below are the latest version of the plugins. | Framework Name | Version | | -------------- | ------- | | React-Native | 7.0.0 | | Flutter | 3.0.0 | | Flutter Inbox | 2.0.0 | | Cordova | 7.0.0 | | Unity | 2.0.0 | The above version is built on top of `11.x.xx` and we strongly recommend you to use the above versions or above. In case, you are not able to update to `11.x.xx` due to some technical limitations or bandwidth issues we have uploaded the last `10.x.xx` version along with the add-on modules on Maven Central. You can update to the below versions. These versions are built on top of `10.6.01` the `10.x.xx` version on Maven Central. | Framework Name | Version | | -------------- | ------- | | React-Native | 6.1.7 | | Flutter | 2.0.3 | | Flutter Inbox | 1.0.2 | | Cordova | 6.1.4 | | Unity | 1.3.1 | # Segment Integration We recommend you migrate to the version published on maven central(`5.1.00` or above) at the earliest to avoid any issues. # Migration for 5.x.xx If you are using the 5.x.xx version of the MoEngage SDK you would just need to change the version to `5.1.00` or above to move to maven central Artifacts.\ Make sure you update the other unbundled/dependent MoEngage SDKs or modules(like Push Amp Plus, Push Templates, etc.) to the compatible version. # Migration for 4.x.xx Update to the latest SDK version `5.1.00` or above. Since it would be a major version update there might be additional code changes required apart from changing the version number in your gradle file(s). Refer to the [Updating to 11.x.xx](/developer-guide/android-sdk/migration/updating-to-11xxx-from-10xxx) document and [Release Notes](/developer-guide/release-notes/android-sdk/2023-and-older-1) for more details.\ Make sure you update the other unbundled/dependent MoEngage SDKs or modules(like Push Amp Plus, Push Templates, etc.) to the compatible version. In case, you are not able to update to `5.x.xx` due to some technical limitations or bandwidth issues we have uploaded the last `4.x.xx` version along with the add-on modules on Maven Central. You can update to the below versions. | Artifact | Version | | ---------------------------- | ------- | | moengage-segment-integration | 4.3.01 | | addon-inbox | 5.3.1 | | cards | 1.2.01 | | hms-pushkit | 1.2.01 | | push-amp-plus | 2.2.01 | | rich-notification | 1.2.02 | # Moving from Manifest to Code based Integration Source: https://moengage.com/docs/developer-guide/android-sdk/migration/moving-from-manifest-to-code-based-integration Migrate your MoEngage Android SDK setup from manifest metadata to code-based initialization. We have deprecated integration on MoEngage SDK via Manifest configuration/tags.\ In the latest integration, you need to initialize the SDK in the `onCreate()` of the application class of your app. Below are the metadata flags you need to remove and equivalent APIs you need to call in the `onCreate()` of your application class.\ If you are already initializing the SDK via code in your Application class you can ignore this. # Adding App Id ## Then ```text wrap theme={null} {/* MANDATORY FIELD: APP ID AS SEEN ON MOENGAGE DASHBOARD APP SETTINGS PAGE */} ``` ## Now ```text wrap theme={null} // this is the instance of the application class and "XXXXXXXXXXX" is the Workspace ID from the dashboard. MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXXX") .build(); MoEngage.initialise(moEngage); ``` # Adding Lifecycle Callbacks ## Then ```text wrap theme={null} MoEHelper.getInstance(getApplicationContext()).autoIntegrate(this); ``` ## Now Remove the above line from your Application class. # Adding meta tags to manifest for push notifications ## Then ```text wrap theme={null} {/* MANDATORY FIELD: SENDER ID , i.e. THE PROJECT NUMBER AS MENTIONED ON GOOGLE CLOUD CONSOLE PROJECTS PAGE */} {/* MANDATORY FIELD: THE NOTIFICATION SMALL ICON WHICH WILL BE USED TO SET TO NOTIFICATIONS POSTED */} {/* MANDATORY FIELD: THE NOTIFICATION LARGE ICON WHICH WILL BE USED TO SET TO NOTIFICATIONS POSTED */} ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .setSenderId("xxxxxxx") // required only if you are using GCM. .setNotificationSmallIcon(R.drawable.icon) .setNotificationLargeIcon(R.drawable.ic_launcher) .build(); MoEngage.initialise(moEngage); ``` # Adding meta tags to Skip GCM Registration ## Then ```text wrap theme={null} ``` ## Now ```text wrap theme={null} new MoEngage.Builder(this, "XXXXXXXXXX") .setSenderId("xxxxxxx") // required only if you are using GCM. .setNotificationSmallIcon(R.drawable.icon) .setNotificationLargeIcon(R.drawable.ic_launcher) .optOutTokenRegistration() .build(); MoEngage.initialise(moEngage); ``` # Showing Multiple Notifications at one go ## Then ```text wrap theme={null} {/* OPTIONAL FIELD: THE NOTIFICATION TYPE WHICH WILL BE USED, SINGLE OR MULTIPLE. DEFAULT BEHAVIOR IS SINGLE */} ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .setSenderId("xxxxxxx") // required only if you are using GCM. .setNotificationSmallIcon(R.drawable.icon) .setNotificationLargeIcon(R.drawable.ic_launcher) .setNotificationType(R.integer.notification_type_multiple) .build(); MoEngage.initialise(moEngage); ``` # Setting notification Color ## Then ```text wrap theme={null} [hex code of color] ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .setSenderId("xxxxxxx") // required only if you are using GCM. .setNotificationSmallIcon(R.drawable.icon) .setNotificationLargeIcon(R.drawable.ic_launcher) .setNotificationColor(R.color.colorAccent) .build(); MoEngage.initialise(moEngage); ``` # Opt-out BackStack creation for Notification ## Then ```text wrap theme={null} PushManager.getInstance().optoutBackStackBuilder(true); ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXX") .optOutBackStackBuilder() .build(); MoEngage.initialise(moEngage); ``` # Opt-out activity tracking ## Then ```text wrap theme={null} ``` ## Now ```text wrap theme={null} ArrayList trackingOptOut = new ArrayList<>(); trackingOptOut.add(SettingsActivity.class); MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXXX") .setTrackingOptOut(trackingOptOut) .build(); MoEngage.initialise(moEngage); ``` # Opt-out NavBar ## Then ```text wrap theme={null} InAppManager.getInstance().optOutNavBar(this,true); ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .optOutNavBar() .build(); MoEngage.initialise(moEngage); ``` # Opt-out Activity from showing InApp ## Then ```text wrap theme={null} ``` ## Now ```text wrap theme={null} ArrayList inAppOptOut = new ArrayList<>(); inAppOptOut.add(MainActivity.class); MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .setInAppOptOut(inAppOptOut) .build(); MoEngage.initialise(moEngage); ``` # Opt-out of MoEngage extras in Deeplink ## Then ```text wrap theme={null} PushManager.getInstance().optOutMoEngageExtras(true); ``` ## Now ```text wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXXXX") .optOutMoEngageExtras() .build(); MoEngage.initialise(moEngage); ``` # Updating to 11.x.xx from 10.x.xx Source: https://moengage.com/docs/developer-guide/android-sdk/migration/updating-to-11xxx-from-10xxx Migrate to MoEngage Android SDK 11.x.xx with updated APIs, Java 8 support, and modular geofence setup. # Behavioral Changes * Target SDK version bumped to API level 29 * Starting SDK version `11.0.00` Geofence is not included when `moe-android-sdk` is added in the application. Refer to the [Location triggered Push](https://developers.moengage.com/hc/en-us/articles/4403443036564) documentation to integrate and use the Geofence module. * SDK has been re-packaged to have clear separation for internal files and exposed classes. Any class with the package name `com.moengage.*.internal.*` should not be used. APIs in these classes can be updated/removed without prior notice and should not be used by integrating applications. * InApp is no longer shown via Activity lifecycle callbacks. To show in-app `showInApp()` should be called in the Activity or Fragment. Refer to the [In-App NATIV](https://developers.moengage.com/hc/en-us/articles/4403652537492) documentation for more details. * Source and Target Compatibility Updated to Java 8. Enable Java 8 in your application if not done already. * In this release, we have updated the hosts used by the SDK. In case you have whitelisted MoEngage endpoints in the network configuration of your application update the endpoints. Refer to the [Network Security Configuration](https://developers.moengage.com/hc/en-us/articles/4401984811796) to know more. * SDK no longer tracks location by default. # Update Removed APIs In version `11.0.00`, we have removed many of the APIs which were long deprecated. If you are still using the deprecated APIs you have to update to the new APIs. Below is a table mapping the equivalents of the removed APIs. Some of the APIs might not have an alternate API as the functionality might have been handled internally or no longer supported. | Then | Now | | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | PushHandler#handlePushPayload (Context, Bundle) | MoEFireBaseHelper#passPushPayload (Context, Bundle) | | PushHandler#handlePushPayload (Context, Map) | MoEFireBaseHelper#passPushPayload (Context, Map) | | MoEFireBaseHelper#setOnNonMoEngage PushReceivedListener (OnNonMoEngagePushReceivedListener) | MoEFireBaseHelper#add EventListener(FirebaseEventListener) | | PushManager#refreshToken(Context, String) | MoEFireBaseHelper#passPushToken (Context, String) | | PushManager#setMessageListener(Object) | MoEPushHelper#setMessageListener (PushMessageListener) | | MoEngageNotificationUtils#isFrom MoEngagePlatform(Context, Bundle) | MoEPushHelper#isFromMoEngagePlatform (Bundle) | | MoEngageNotificationUtils#isFromMoEngagePlatform (Context, Map) | MoEPushHelper#isFromMoEngagePlatform (Map) | | PushMessageListener#onCreateNotification(Context, Bundle, ConfigurationProvider) | PushMessageListener#onCreateNotification (Context, NotificationPayload) | | PushManager#getPushHandler() | NA | | MoEPushHelper#handlePushPayload (Context, Map) | Use `passPushPayload()`  of each push module. | | MoEPushHelper#handlePushPayload (Context, Bundle) | Use `passPushPayload()`  of each push module. | | MoEngage.Builder#optOutBackgroundSync() | MoEngage.Builder#configureDataSync (DataSyncConfig) | | MoEngage.Builder.optOutPeriodicFlush() | MoEngage.Builder#configureDataSync (DataSyncConfig) | | MoEngage.Builder.setFlushInterval(long interval) | MoEngage.Builder#configureDataSync (DataSyncConfig) | | MoEngage.Builder.optOutLocationTracking() | NA | | MoEngage.Builder.optOutGeofenceBackgroundSync() | MoEngage.Builder#configureGeofence (GeofenceConfig) | | MoEngage.Builder.enableBackgroundLocationFetch() | NA | | MoEngage.Builder.enableLocationServices() | MoEngage.Builder#configureGeofence (GeofenceConfig) | | MoEngage.Builder.optOutRealTime TriggerBackgroundSync() | MoEngage.Builder#configureRealTimeTrigger (RttConfig) | | MoEngage.Builder.redirectDataToRegion (DATA\_REGION) | MoEngage.Builder#setDataCenter (DataCenter) | | MoEngage.Builder#optOutDefaultInAppDisplay() | NA | | MoEngage.Builder#optOutActivityTracking(List) | MoEngage.Builder#configureTrackingOptOut (TrackingOptOutConfig) | | MoEngage.Builder#optOutGAIDCollection() | MoEngage.Builder#configureTrackingOptOut (TrackingOptOutConfig) | | MoEngage.Builder#optOutAndroidIdCollection() | MoEngage.Builder#configureTrackingOptOut (TrackingOptOutConfig) | | MoEngage.Builder#optOutCarrierNameCollection() | MoEngage.Builder#configureTrackingOptOut (TrackingOptOutConfig) | | MoEngage.Builder#optOutDeviceAttributeCollection() | MoEngage.Builder#configureTrackingOptOut (TrackingOptOutConfig) | | MoEngage.Builder.setNotificationType() | MoEngage.Builder#configure NotificationMetaData(NotificationConfig) | | MoEngage.Builder#setDateFormatForCard (String) | MoEngage.Builder#configureCards (CardConfig) | | MoEngage.Builder#setEmptyInboxImageForCard (int) | MoEngage.Builder#configureCards (CardConfig) | | MoEngage.Builder#setPlaceHolderImageForCard (int) | MoEngage.Builder#configureCards (CardConfig) | | MoEHelper#trackEvent(String) | MoEHelper#trackEvent (String, Properties) | | MoEHelper#trackEvent(String, JSONObject) | MoEHelper#trackEvent(String, Properties) | | MoEHelper#trackEvent(String, Map) | MoEHelper#trackEvent(String, Properties) | | MoEHelper#setUserAttribute(String, String, String) | MoEHelper#setUserAttribute(String, Date) | | MoEHelper#setGender(String) | MoEHelper#setGender(UserGender) | | MoEHelper#fetchDeviceTriggersIfRequired() | MoERttHelper#syncTriggers(Context) | | MoEHelper#registerAppBackgroundListener (OnAppBackgroundListener) | MoECallbacks#addAppBackgroundListener (OnAppBackgroundListener) | | MoEHelper#unregisterAppBackgroundListener() | MoECallbacks#removeAppBackgroundListener (OnAppBackgroundListener) | | MoEHelper#setOnLogoutCompleteListener (OnLogoutCompleteListener) | MoECallbacks#addLogoutCompleteListener (OnLogoutCompleteListener) | | MoEHelper#removeLogoutCompleteListener() | MoECallbacks#removeLogoutListener (OnLogoutCompleteListener) | # APIs Deprecated in 11.0.00 In version `11.0.00` we have deprecated a few APIs to improve performance and better support in the future. Below is the list of deprecated APIs and their alternatives, please update to the latest methods. | Then | Now | | --------------------------------------------------------------- | --------------------------------------------------------------------- | | MoEngage.Builder #setNotificationLargeIcon(int) | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationSmallIcon(int) | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationColor(int) | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationTone(String) | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#enableMultiple NotificationInDrawer(boolean) | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#optOutBackStackBuilder() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#optOutNotificationLargeIcon() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#enableLogsForSignedBuild() | MoEngage.Builder#configureLogs (LogConfig) | | MoEngage.Builder#enableLogs(int) | MoEngage.Builder#configureLogs (LogConfig) | | MoEngage.Builder#enablePushKit TokenRegistration() | MoEngage.Builder#configurePushKit (PushKitConfig) | | MoEngage.Builder#enableSegmentIntegration() | MoEngage.Builder#enablePartnerIntegration (IntegrationPartner) | | MoEHelper#setUniqueId(double) | MoEHelper#setUniqueId(String) | | MoEHelper#setUniqueId(float) | MoEHelper#setUniqueId(String) | | MoEHelper#setUniqueId(int) | MoEHelper#setUniqueId(String) | | MoEHelper#setUniqueId(long) | MoEHelper#setUniqueId(String) | | MoEHelper#setAlias(double) | MoEHelper#setAlias(String) | | MoEHelper#setAlias(float) | MoEHelper#setAlias(String) | | MoEHelper#setAlias(int) | MoEHelper#setAlias(String) | # Updating to 12.x.xx from 11.x.xx Source: https://moengage.com/docs/developer-guide/android-sdk/migration/updating-to-12xxx-from-11xxx Migrate to MoEngage Android SDK 12.x.xx with updated build configs and modularized InApp and Push. # Behavioral Changes * Build Configuration updated to the following * compileSdk 30 * minSdk 21 * targetSdk 30 * Starting from SDK version 12.0.00 following features are not integrated by default when adding moe-android-sdk as a dependency. If you are using these features refer to their respective integration document and make update the dependencies. * [InApp](https://developers.moengage.com/hc/en-us/articles/4403652537492-In-App-NATIV) * [Push Amplification](https://developers.moengage.com/hc/en-us/articles/4650416409876) * [Device Trigger](https://developers.moengage.com/hc/en-us/articles/4649815712532) * APIs to initialize the SDK now throws [*IllegalStateException*](https://developer.android.com/reference/java/lang/IllegalStateException) in case App-id is null or empty. ## External Library Version updates * androidx.core:core 1.3.1 --> 1.6.0 * androidx.appcompat:appcompat 1.2.0 --> 1.3.1 * androidx.lifecycle:lifecycle-process 2.2.0 --> 2.4.0 * com.google.firebase:firebase-messaging 22.0.0 --> 23.0.0 * Kotlin Standard Library 1.4.20 --> 1.6.0 # Update Removed initialization APIs | Then | Now | | --------------------------------------------------------- | --------------------------------------------------------------------- | | MoEngage.Builder#optOutInAppOnActivity() | MoEngage.Builder#configureInApps (InAppConfig) | | MoEngage.Builder#optOutNavBar() | MoEngage.Builder#configureInApps (InAppConfig) | | MoEngage.Builder#optOutBackStackBuilder() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#enableMultipleNotificationInDrawer() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationTone() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationColor() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationSmallIcon() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#setNotificationLargeIcon() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#optOutNotificationLargeIcon() | MoEngage.Builder#configureNotificationMetaData (NotificationConfig) | | MoEngage.Builder#optOutTokenRegistration() | MoEngage.Builder#configureFcm (FcmConfig) | | MoEngage.Builder#setSenderId() | Support removed for sender id | | MoEngage.Builder#configureMiPush(String, String, Boolean) | MoEngage.Builder#configureMiPush (MiPushConfig) | | MoEngage.Builder#enablePushKitTokenRegistration() | MoEngage.Builder#configurePushKit (PushKitConfig) | | MoEngage.Builder#enableLogsForSignedBuild() | MoEngage.Builder#configureLogs (LogConfig) | | MoEngage.Builder#enableLogs() | MoEngage.Builder#configureLogs (LogConfig) | | MoEngage.Builder#enableSegmentIntegration() | MoEngage.Builder#enablePartnerIntegration (IntegrationPartner) | # Update removed methods in the core module | Then | Now | | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | MoECallbacks#addLogoutCompleteListener (OnLogoutCompleteListener) | MoECoreHelper#addLogoutCompleteListener (OnLogoutCompleteListener) | | MoECallbacks#removeLogoutListener (OnLogoutCompleteListener) | MoECoreHelper#removeLogoutListener (OnLogoutCompleteListener) | | MoECallbacks#addAppBackgroundListener (AppBackgroundListener) | MoECoreHelper#addAppBackgroundListener (AppBackgroundListener) | | MoECallbacks#removeAppBackgroundListener (AppBackgroundListener) | MoECoreHelper#removeAppBackgroundListener (AppBackgroundListener) | | MoEHelper#registerActivityLifecycle() | Support Removed | | MoEHelper#unregisterLifecycleCallbacks() | Support Removed | | MoEHelper#registerProcessLifecycleObserver() | Support Removed | | MoEHelper#unRegisterProcessLifecycleObserver() | Support Removed | | MoEHelper#trackEvent (String, PayloadBuilder) | MoEAnalyticsHelper#trackEvent (String, Properties) | | MoEHelper#syncInteractionDataNow() | MoECoreHelper#syncInteractionData() | | MoEHelper#setAppContext (List) | MoEInAppHelper#setInAppContext (Set) | | MoEngage#enableSdk(Context) | enableSdk(Context) or MoESdkStateHelper#enableSdk(Context) | | MoEngage#disableSdk(Context) | disableSdk(Context) or MoESdkStateHelper#disableSdk(Context) | | MoEngage#optOutDataTracking(Context, boolean) | enableDataTracking(Context)/disableDataTracking(Context) or MoESdkStateHelper#enableDataTracking(Context)/ MoESdkStateHelper#disableDataTracking(Context) | | MoEngage#optOutPushNotification(Context, boolean) | Support Removed | | MoEngage#optOutInAppNotification(Context, boolean) | Support Removed | | MoEngage#initialise(MoEngage, Boolean) | MoEngage#initialiseDefaultIstance (MoEngage, SdkState) | | MoEngage#initialise(MoEngage) | MoEngage#initialiseDefaultIstance (MoEngage) | # Changes in Push * Support for Notification tone dropped * [*NotificationPayload*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.model/-notification-payload/index.html)restructured for easier use. * Methods removed or replaced | Then | Now | | -------------------------------------------------------- | ------------------------------------------------------------- | | PushMessageListener#onHandleRedirection() | PushMessageListener#onNotificationClick() | | MoEPushHelper#setMessageListener (PushMessageListener) | MoEPushHelper#registerMessageListener (PushMessageListener) | ## Change in Firebase Messaging *FirebaseEventListener* removed, instead use the following callbacks * [*TokenAvailableListener*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.listener/-token-available-listener/index.html) for getting the push token whenever it is generated. * [*NonMoEngagePushListener*](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase.listener/-non-mo-engage-push-listener/index.html) for getting the callback whenever a push is received which is not from MoEngage Server. * Following methods removed are removed *MoEFireHelper* * setEventListener(FirebaseEventListener) * addEventListener(FirebaseEventListener) Instead, use the methods provided for adding TokenAvailableListener and NonMoEngagePushListener. ## Change in HMS Push Kit *PushKitEventListener* removed, instead use the following callbacks * [*TokenAvailableListener*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.listener/-token-available-listener/index.html) for getting the push token whenever it is generated. * [*NonMoEngagePushListener*](https://moengage.github.io/android-api-reference/hms-pushkit/com.moengage.hms.pushkit.listener/-non-mo-engage-push-listener/index.html) for getting the callback whenever a push is received which is not from MoEngage Server. * Following methods removed are removed *MoEPushKitHelper* * setEventListener(PushKitEventListener) * addEventListener(PushKitEventListener) Refer to the [Configuring HMS Push Kit](https://developers.moengage.com/hc/en-us/articles/4403466195732) documentation to know more about how to set the listener. # Changes in InApp InAppMessageListener removed instead use the following callbacks * *OnClickActionListener* for in-app click callback. * [*SelfHandledAvailableListener*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-self-handled-available-listener/index.html) for callbacks when Self handled campaigns are available. * [*InAppLifeCycleListener*](https://moengage.github.io/android-api-reference/inapp/com.moengage.inapp.listeners/-in-app-life-cycle-listener/index.html) for in-app lifecycle callbacks like shown, dismiss. Refer to the [InApp](https://developers.moengage.com/hc/en-us/articles/4403652537492) documentation to know more on how to set the listener. Methods removed from *MoEInAppHelper* | Then | Now | | ------------------------------------------- | ------------------------------------------------------------------------- | | MoEInAppHelper#getSelfHandledInApp(Context) | MoEInAppHelper#getSelfHandledInApp(Context, SelfHandledAvailableListener) | # Changes in Inbox Below are method signature changes | Then | Now | | --------------------------------------------------------- | -------------------------------------------------------------- | | OnMessagesAvailableListener#onMessagesAvailable (List) | OnMessagesAvailableListener#onMessagesAvailable (InboxData) | | UnClickedCountListener#onCountAvailable (Long) | UnClickedCountListener#onCountAvailable (UnClickedCountData) | | MoEInboxHelper#fetchMessagesByTag() returns List | MoEInboxHelper#fetchMessagesByTag() returns InboxData | | MoEInboxHelper#fetchAllMessages() returns List | MoEInboxHelper#fetchAllMessages() returns InboxData | | MoEInboxHelper#getUnClickedMessagesCount() returns Long | MoEInboxHelper#fetchAllMessages() returns UnClickedCountData | | OnMessageClickListener#onMessageClick (InboxMessage) | OnMessageClickListener#onMessageClick (MessageClickData) | # Android 12 Source: https://moengage.com/docs/developer-guide/android-sdk/os-updates/android-12 Review Android 12 behavior changes that affect push notifications and deep links in MoEngage campaigns. Android 12 is a major version update of the Android Operating System, a yearly release cycle. The major release changes are detailed in the [Android Official Release Notes](https://developer.android.com/about/versions/12/release-notes). The following are the major behavior changes impacting the MoEngage Platform or MoEngage Android SDK.  The changes are divided into two parts. First, that affects all the applications and the second that affect only the applications targeting Android 12. # Behavior changes: all apps The following behavior changes apply to all apps running on Android 12, regardless of **targetSdkVersion**. ## Web intent resolution Android 12 (API level 31) and later, a generic web intent resolves to an activity in your app, only if your app is approved for the specific domain contained in that web intent. If your app is not approved for the domain, the web intent resolves to the user's default browser app instead. Apps get approval by doing one of the following: * Verify the domain using the [Android App Links](https://developer.android.com/about/versions/12/web-intent-resolution#android-app-links). * Manually [associate your app with the domain](https://developer.android.com/about/versions/12/web-intent-resolution#request-user-associate-app-with-domain) in system settings by the user. For more information, refer to [Android Web Intent documentation](https://developer.android.com/about/versions/12/web-intent-resolution). ## How does it affect you? If you are using **http(s)** deep links in your campaigns (Push/InApp/Cards) and the links are not configured as [App Links](https://developer.android.com/training/app-links) in your application, users would be navigated to the browser on devices running Android 12. ## How to fix it? MoEngage recommends that you configure App Links in your application. Alternatively, edit the campaigns to update the links, if you already have app schema deep-links (example **example://gizmos**) configured in your application for the same activities. # Behavior changes: Apps targeting Android 12 The following behavior changes apply exclusively to apps that are targeting Android 12 or later, that is **targetSdkVersion** is set to API level 31 or above. ## Pending intents mutability If your app targets Android 12, specify the mutability of each [PendingIntent](https://developer.android.com/reference/android/app/PendingIntent) object that your app creates. The additional requirement improves your app security. For more information, refer to [Android release notes](https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability). ## How does it affect you? If your application **targetSdkVersion** is 31 and not updated to the latest version of MoEngage SDK (**11.4.00** or later), push notifications would not be displayed on Android 12 devices. ## How to fix it? Update to the latest MoEngage SDK (**11.4.00** or later) along with the update of **targetSdkVersion** to API level 31. ## Custom notifications Android 12 changes the appearance and behavior of fully [custom notifications](https://developer.android.com/training/notify-user/custom-notification). Previous versions of custom notifications used the entire notification area and provide layouts and styles. This resulted in anti-patterns confusing users or cause layout compatibility issues on different devices. For apps targeting Android 12, notifications with custom content views will no longer use the full notification area instead, the system defined standard template is applied. ## How does it affect you? If your application **targetSdkVersion** is 31 and the **rich-notification** version is either **2.2.01** or previous versions, templates are displayed as truncated or broken on Android 12 devices. ## How to fix it? Update the rich-notification version to the latest version(2.3.00 or later). MoEngage has temporarily disabled templates when the application **targetSdkVersion** is 31 and the device is running Android 12. MoEngage support for templates with the new specifications for Android 12 will be available in future releases. # Changes in backup and restore Backup and restore functionality is changed for apps that run on and target Android 12 (API level 31). Android backup and restore have two forms: * **Cloud backups:** User data is stored in the Google Drive of the user for restoring data on that device or a new device. * **Device-to-device (D2D) transfers:** User data is sent directly to the new device of the user from the older device of the user by using a cable. For more information on how data is backed up and restored, refer to [Back up user data with Auto Backup](https://developer.android.com/guide/topics/data/autobackup) and [Back up key-value pairs with Android Backup Service](https://developer.android.com/guide/topics/data/keyvaluebackup). ## D2D transfer functionality changes For apps running on and targeting Android 12 and higher: * Specifying **android:allowBackup:"false"**  does disable backups to Google Drive, but doesn’t disable D2D transfers for the app. * [Specifying include and exclude rules](https://developer.android.com/guide/topics/data/autobackup#IncludingFiles) with the XML configuration mechanism no longer affects D2D transfers, though it still affects Google Drive backups. To specify rules for D2D transfers, you must use the new configuration format. # New include and exclude format Apps running on and targeting Android 12 and later use a different XML configuration format. The new format differentiates between Google Drive backup and D2D transfer by specifying include and exclude rules separately for cloud backups and for D2D transfer. Optionally, you can also use the new format to specify rules for backup, in which case the old configuration is ignored. ```XML XML wrap theme={null} ... ... ... ... ... ... ``` ## How does it affect you? If your application **targetSdkVersion** is 31, the backup includes MoEngage SDK identifiers backed up and restored after re-install. The restoration of the identifier results in your data being corrupted and the user not being reachable using push notifications. ## How to fix it? Ensure to add the configuration in the updated format. For more information, refer to [Exclude MoEngage Storage File from Auto Backup](/developer-guide/android-sdk/sdk-integration/basic-integration/exclude-moengage-storage-file-from-auto-backup). While updating the SDK version, please check the compatibility of additional modules and update them accordingly. # SDK Performance Source: https://moengage.com/docs/developer-guide/android-sdk/performance/sdk-performance Review MoEngage Android SDK performance benchmarks for initialization time, memory, and battery impact. Keeping the SDK performant is of paramount importance to us and we constantly try to improve the performance with each release. Performance includes the time taken to initialize the SDK, within how many milliseconds a method returns, the memory footprint of the SDK when the application is running, battery drainage due to background work, and so on. # SDK Initialization time We recommend initializing the SDK on the Main Thread in the [*onCreate()*](https://developer.android.com/reference/android/app/Application#onCreate\(\)) of your Application class, hence it is important for us to keep the initialization simple and fast to ensure it does not affect the application start-up time as start-up time is important for a good user experience.\ The initialization is approximately around 1-5 milliseconds on average. We have tested this on various OEMs and the results seem to be consistent.\ Refer to the below table for more details: | Device | Device Details | Time (in milliseconds) | | -------------- | --------------------- | ---------------------- | | Google Pixel 2 | Android 11 4 GB RAM | 0.878593 | | Samsung A51 | Android 10 6 GB RAM | 1.95223 | | One Plus 7 | Android 10 6 GB RAM | 0.365365 | | Mi Y9 | Android 9 4 GB RAM | 2.658177 | | Vivo Y51A | Android 7 3 GB RAM | 1.667916 | | Pixel 4a | Android 12 6 GB RAM | 0.446823 | | Tab A7 | Andriod 11 3 GB RAM | 0.889791 | | Mi K20 Pro | Android 10 6 GB RAM | 0.553854 | # SDK Size Impact Source: https://moengage.com/docs/developer-guide/android-sdk/performance/sdk-size-impact Review the APK and App Bundle size impact of each MoEngage Android SDK artifact. SDK size is one of the important considerations for us as the inclusion of SDKs can significantly influence the final APK / App Bundle size, affecting the user experience and download time. So, we always aim to keep the impact as low as possible on the final APK / App Bundle size. # MoEngage SDKs Refer to the below table for details about the impact on APK / App Bundle size due to different MoEngage artifacts. Version Catalog (used for size impact calculation): ***3.2.2*** | Artifact Id | Version | Size Impact (Approx. Kilobytes) | | -------------------------------------------------------------- | -------- | ------------------------------- | | cards-core | 1.6.0 | 33 KB | | cards-ui | 1.6.1 | 277 KB | | encrypted-storage | 1.3.0 | 1 KB | | geofence | 3.4.0 | 27 KB | | hms-pushkit | 4.7.0 | 129 KB | | inapp | 7.1.1 | 148 KB | | inbox-core | 2.6.0 | 7 KB | | inbox-ui | 2.6.0 | 171 KB | | integration-verifier | 4.4.0 | 62 KB | | moe-android-sdk | 12.10.02 | 227 KB | | moengage-segment-kotlin-destination (includes moe-android-sdk) | 1.5.0 | 227 KB | | push-amp | 4.6.0 | 6 KB | | push-amp-plus | 6.6.0 | 7 KB | | realtime-trigger | 2.6.0 | 26 KB | | rich-notification | 4.7.2 | 155 KB | | security | 2.6.0 | 2 KB | # External SDKs There are some external dependencies that the Application must include while using the MoEngage SDK. Refer to the below table to get the impact due to the external dependencies. | Dependency | Version | Size Impact (Approx. Kilobytes) | | ------------------ | --------- | ------------------------------- | | Firebase Messaging | 23.1.2 | 158 KB | | HMS Push SDK | 6.3.0.304 | 443 KB | | MI Push SDK | 5.1.1 | 222 KB | # Callbacks and Customisation Source: https://moengage.com/docs/developer-guide/android-sdk/push/advanced/callbacks-and-customisation Customize push notification display and behavior in your Android app using the MoEngage PushMessageListener. **Advanced Customization** Support for advanced use cases where the application wants to customize or alter the default behavior of the MoEngage SDK. MoEngage SDK allows the client application to optionally customize the notification display and extend/customize the behavior of the notification. Some of the possible customizations are deciding whether to show a notification or not, and tweaking the *NotificationCompat.Builder* object, etc. To do so you need to extend a class called [PushMessageListener](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/index.html) provided by the MoEngage SDK and pass on the instance of this class to the MoEngage SDK. Once you have done this you can override the default implementation as per the requirement. Let's look at the above steps in more detail. # Extending PushMessageListener The first thing required to customize the notification is creating a class that extends [*PushMessageListener*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/index.html). We will call this class **CustomPushMessageListener** (only for illustration purposes you can have any class name you want). The barebones of this class would look something like below. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { } ``` ```java Java theme={null} public class CustomPushMessageListener extends PushMessageListener { } ``` # Passing the instance of CustomPushMessageListener to MoEngage SDK You need to pass on the instance of *CustomPushMessageListener* to the MoEngage SDK in the *onCreate()* of the *Application* class. You need to pass the instance to [MoEPushHelper.getInstance().registerMessageListener()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase/\[android-jvm]-mo-e-push-helper/register-message-listener.html) API. A sample call is described. ```kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().registerMessageListener(CustomPushMessageListener()) ``` ```java Java wrap theme={null} MoEPushHelper.getInstance().registerMessageListener(new CustomPushMessageListener()); ``` # Optionally control notification display To control whether a notification is shown to the user or not, you need to override [isNotificationRequired()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/is-notification-required.html) in the *CustomPushMessageListener* class created above.\ If you intend to show the notification overridden, the implementation should return **true** or **false**. The structure for implementation is described as follows:\ If this method returns **false,** this notification is discarded by the SDK; that is, the notification will not be displayed on the device, and the impression will not be tracked. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { // decide whether notification should be shown or not. override fun isNotificationRequired(context: Context, payload: Bundle): Boolean { // app's logic to decide whether to show notification or not. // for illustration purpose reading notification preference from SharedPreferences and // deciding whether to show notification or not. Logic can vary from application to // application. val preferences = context.getSharedPreferences("demoapp", 0) return preferences.getBoolean("notification_preference", true) } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { // decide whether a notification should be shown or not. @Override public boolean isNotificationRequired(Context context, Bundle payload) { // app's logic to decide whether to show a notification or not. //For illustration purposes reading notification preference from SharedPreferences and // deciding whether to show a notification or not. Logic can vary from application to // application. SharedPreferences preferences = context.getSharedPreferences("demoapp", 0); return preferences.getBoolean("notification_preference", true); } } ``` For more information, refer to [API Reference](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/is-notification-required.html). # Notification Received Callback To receive a callback whenever a push is received, override the [onNotificationReceived()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/on-notification-received.html) in the *CustomPushMessageListener* class. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun onNotificationReceived(context: Context, payload: Bundle) { super.onNotificationReceived(context, payload) //callback for push notification received. } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void onNotificationReceived(Context context, Bundle payload) { super.onNotificationReceived(context, payload); //callback for push notification received. } } ``` # Notification Clicked Callback To receive a callback whenever a push is clicked, override the [onNotificationClicked()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/on-notification-click.html) in the *CustomPushMessageListener* class created as described in the Notification Received Callback.\ This method doubles as a callback and can be used for handling redirection. If you want to handle redirection on notification, click the method should return true, or else false. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun onNotificationClicked(activity: Activity, payload: Bundle) { // If you want to handle redirection on notification, click the method should return true, or else false. return false } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void onNotificationClicked(Activity activity, Bundle payload) { // If you want to handle redirection on notification, click the method should return true, or else false. return false; } } ``` # Notification Cleared Callback To receive a callback whenever a push is cleared, override the [onNotificationCleared()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/on-notification-cleared.html) in the *CustomPushMessageListener* class created above. ```kotlin Kotlin wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void onNotificationCleared(Context context, Bundle payload) { super.onNotificationCleared(context, payload); // callback for notification cleared. } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void onNotificationCleared(Context context, Bundle payload) { super.onNotificationCleared(context, payload); // callback for notification cleared. } } ``` # Custom Action on Action Button Click To use a custom action on the Action Button click override the [handleCustomAction()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/handle-custom-action.html) in the *CustomPushMessageListener* class created above. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun handleCustomAction(context: Context, payload: String) { super.handleCustomAction(context, payload) // callback for notification custom action } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void handleCustomAction(Context context, String payload) { super.handleCustomAction(context, payload); // callback for notification custom action } } ``` # Customize Notification To further customize the notification object, override the [customizeNotification()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/customize-notification.html). This allows for additional settings to be added or modified, such as vibration patterns/LED colors, etc. It is important to note that the super method should be called before adding any customizations to ensure that the default settings are applied. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun customizeNotification(notification: Notification, context: Context, payload: Bundle) { super.customizeNotification(notification, context, payload) // You can customize the `notification` object here } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void customizeNotification(Notification notification, Context context, Bundle payload) { super.customizeNotification(notification, context, payload); // You can customize the `notification` object here } } ``` # Customize Notification Builder The SDK provides the [customizeNotificationBuilder()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.push/\[android-jvm]-push-message-listener/customize-notification-builder.html) callback to customize the notification builder object as needed. This feature allows developers to update various properties of the notification builder, such as the channel ID, the auto-dismiss time, etc. It is important to note that the super method should be called before adding any customizations to ensure that the default settings are applied. ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun customizeNotificationBuilder(notificationBuilder: NotificationCompat.Builder, context: Context, notificationPayload: NotificationPayload) { super.customizeNotificationBuilder(notificationBuilder, context, notificationPayload) // You can customize the `notificationBuilder` object here } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void customizeNotificationBuilder(Notification notification, Context context, NotificationPayload notificationPayload) { super.customizeNotificationBuilder(notification, context, payload); // You can customize the `notificationBuilder` object here } } ``` # Self-handled Notification Received Callback   When you use the SDK callback approach by registering a `PushMessageListener`, the MoEngage SDK provides a dedicated method for self-handled notifications. **SDK version**: The self-handled notification check is supported starting from Android SDK version **14.06.00**. **Automatic Impression Tracking:** When using this callback, the MoEngage SDK **automatically tracks notification impressions**. You do not need to call `logNotificationReceived`. You only need to handle the display and manually track clicks if a custom UI is shown. To receive this callback, override `onSelfHandledNotificationReceived()` in your custom listener class: ```kotlin Kotlin wrap theme={null} class CustomPushMessageListener : PushMessageListener() { override fun onSelfHandledNotificationReceived(context: Context, payload: Bundle) { // Impression is already logged by the SDK automatically // 1. Logic to handle background data (e.g., sync, logout) // 2. Logic to build and show a custom notification UI (if required) } } ``` ```java Java wrap theme={null} public class CustomPushMessageListener extends PushMessageListener { @Override public void onSelfHandledNotificationReceived(@NonNull Context context, @NonNull Bundle payload) { // Impression is already logged by the SDK automatically // 1. Logic to handle background data (e.g., sync, logout) // 2. Logic to build and show a custom notification UI (if required) } } ``` For more information on the payload structure received in the `Bundle`, refer to [Background Update Templates](https://help.moengage.com/hc/en-us/articles/4415622460948-Push-Templates#h_01HCM6A9GPQWGQBKTQ7504CZAK). # Push Display Handled by Application Source: https://moengage.com/docs/developer-guide/android-sdk/push/advanced/push-display-handled-by-application Handle push notification display yourself and track impressions and clicks with the MoEngage Android SDK. This section is only required for very advanced use cases where the application needs to handle the push display on the client side. We believe that the customization provided in [Advanced Push Configuration](/android-sdk/push/advanced/callbacks-and-customisation) should solve most of your use-cases. Refer to this document only if your use-cases cannot be satisfied by the customizations provided in the [Advanced Push Configuration](/android-sdk/push/advanced/callbacks-and-customisation) section. If the push notification display is handled by the application we need some help from the application to show Push Campaign statistics namely Impressions and Clicks. # Tracking Notification Impressions The application needs to notify the SDK if a push from the MoEngage Platform is received via Firebase Cloud Messaging(FCM). SDK provides a helper API [isFromMoEngagePlatform()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase/-mo-e-push-helper/is-from-mo-engage-platform.html) to check whether push is received from the MoEngage Platform or not. Use this API to check if the received push is from the MoEngage Platform and call [logNotificationReceived()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase/-mo-e-push-helper/log-notification-received.html) to track notification impressions. ```kotlin Kotlin wrap theme={null} if (MoEPushHelper.getInstance().isFromMoEngagePlatform(pushPayload)) { MoEPushHelper.getInstance().logNotificationReceived(context, pushPayload) } ``` ```java Java wrap theme={null} if (MoEPushHelper.getInstance().isFromMoEngagePlatform(pushPayload)) { MoEPushHelper.getInstance().logNotificationReceived(context, pushPayload); } ``` # Tracking Notification Clicks After the notification is clicked application needs to notify the SDK that a notification is clicked for the SDK to track notification clicks. For SDK to track notification clicks and user sessions accurately, ensure: * The Push payload received from FCM is added as extras to the Pending intent * The [logNotificationClick()](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase/-mo-e-push-helper/log-notification-click.html) API is called from **onCreate()** of your Activity which is inflated on notification click. ```kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().logNotificationClick(applicationContext, intent) ``` ```java Java wrap theme={null} MoEPushHelper.getInstance().logNotificationClick(getApplicationContext(), getIntent()); ``` # Background Update Template (Manual Approach) * **SDK version**: The self-handled notification check is supported starting from Android SDK version **14.06.00**. * **Payload information**: For more information on the payload structure and available keys, refer to [Background Update Template](https://help.moengage.com/hc/en-us/articles/4415622460948-Push-Templates#h_01HCM6A9GPQWGQBKTQ7504CZAK). If you are using a custom `PushMessageListener`,MoEngage recommends using the SDK Callback approach where impressions are tracked automatically. Refer to the [Callback Customization](/android-sdk/push/advanced/callbacks-and-customisation#Self-handled-Notification-Received-Callback) section for more details. Use this approach if you have a custom Firebase Messaging Service and wish to manually intercept the MoEngage payload. When handling manually, **you must manually track notification impressions**. ```kotlin Kotlin wrap theme={null} override fun onMessageReceived(remoteMessage: RemoteMessage) { val payload = remoteMessage.data // Step 1: Check if the push is from MoEngage platform if (MoEPushHelper.getInstance().isFromMoEngagePlatform(payload)) { // Step 2: Check if it's a self-handled notification if (MoEPushHelper.getInstance().isSelfHandledNotification(payload)) { // Log impression manually for self-handled pushes MoEPushHelper.getInstance().logNotificationReceived(applicationContext, payload) // Handle Display of notification or custom logic here return } else { // For non-self-handled, pass to SDK for default handling MoEFireBaseHelper.getInstance().passPushPayload(applicationContext, payload) } } } ``` ```java Java wrap theme={null} @Override public void onMessageReceived(RemoteMessage remoteMessage) { Map payload = remoteMessage.getData(); // Step 1: Check if the push is from MoEngage platform if (MoEPushHelper.getInstance().isFromMoEngagePlatform(payload)) { // Step 2: Check if it's a self-handled notification if (MoEPushHelper.getInstance().isSelfHandledNotification(payload)) { // Log impression manually for self-handled pushes MoEPushHelper.getInstance().logNotificationReceived(getApplicationContext(), payload); // Handle Display of notification or custom logic here return; } else { // For non-self-handled, pass to SDK for default handling MoEFireBaseHelper.getInstance().passPushPayload(getApplicationContext(), payload); } } } ``` # Callback for push delivered by Push Amp Push-Amp notification is not delivered via FCM, it is delivered directly via MoEngage. You need to set up a callback for receiving payload for messages/campaigns. ### Steps: 1. Setup a callback for notification received. For more information, refer to the [notification received callback documentation](/android-sdk/push/advanced/callbacks-and-customisation). 2. Mark notification as not required. This step is important, if not implemented correctly end-user might end up with two notifications. For more information, refer to the [notification received callback documentation](/android-sdk/push/advanced/callbacks-and-customisation). In this case, **isNotificationRequired()** should always return false. # Handling re-direction for push delivered by Push Amp+ Whenever campaigns are delivered using Push Amp+ due to a technical limitation push display cannot be handled by the application. The application gets a callback only once the user clicks on the notification. For more information about how to register for push redirection callback, refer to the [notification clicked callback documentation](/android-sdk/push/advanced/callbacks-and-customisation). # Related Documents [MoEngage Andriod Push Handling Samples](https://github.com/moengage/Android-Sample/tree/app_handling_push) # FCM Authentication Source: https://moengage.com/docs/developer-guide/android-sdk/push/basic/fcm-authentication Generate and upload an FCM private key to the MoEngage Dashboard for Android push notification delivery. FCM Authentication is one of the methods to enable sending Push notifications to your app installed on Android devices. The FCM Authentication token is used to authorize server requests to Firebase services. You must generate the authentication token and upload it to the MoEngage Dashboard to send Push notifications to Android users. You have an app created on the Firebase console. # Authorize Server Requests to Firebase Services You can authorize server requests to Firebase services using the Private key. FCM Private key is a service account JSON file that contains the details of the Private key generated for authenticating the service account. ## Steps to Generate a Private Key Login to the [Firebase console](https://console.firebase.google.com/) with your credentials. 1. Select your project. 2. In the top left pane, click the settings icon beside **Project Overview**. 3. Select **Project settings**. FCM Step1 4. On the **Project Settings** page, navigate to the **Service accounts** tab. Firebase Admin SDK 5. Click **Generate new private key**. The language you select doesn't matter because we just download the JSON file. The language you select provides you a sample code if you are implementing the FCM communication. MoEngage already does this for you, so select any language and generate the key. 6. Confirm the same by clicking **Generate Key**. This will generate a JSON file containing the Private key. 7. Download the JSON file and upload it to the MoEngage Dashboard at **Settings** > **Channel** > **Push** > **App Push** > **Android** > **FCM Authentication** > **Private key file (Recommended)**. Mceclip4 8. After the JSON is configured, enable FCM in the [cloud console](https://console.cloud.google.com/apis/library/fcm.googleapis.com). Enable FCM # Changes in Sending Speed with Private Key Configuration The Firebase Cloud Messaging API has a default rate limit of 600,000 requests per minute. For more information, refer [here](https://firebase.google.com/support/faq#fcm-depr-rampup). If your account reaches that limit, FCM may drop those notifications with the following error: | Error | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | FCM Message rate exceeded (Quotaexceededforquotametric…) | Sending speed is exceeding the service capacity for your FCM account. Requests beyond serving capacity are rejected to limit the ingress flow rate. This happens because of multiple campaigns being triggered at the same time at high speeds. Consider spacing out campaigns or reducing request limits in the campaign delivery control. | With the reduction in default FCM API rate limits to 600,000 RPM, we will be changing the maximum allowed throttle speed for Push notifications to 500,000 RPM to ensure a single campaign does not breach the project limit. This change will apply to new and existing campaigns. You may still see drops because of multiple campaigns being triggered together. To reduce such errors, you can take one of the following approaches depending on your use case: * **Reduce the campaign sending speed** If you are seeing 'FCM Message rate exceeded' a lot in one-time and periodic campaigns, you might be exceeding the sending capacity beyond your allotted quota. We recommend reducing the request limits in the campaign delivery control to avoid exceeding the quota.\ Because of the default rate limit of 600,000 requests per minute for FCM, we recommend setting it to a lower limit (\~200,000 requests per minute) to accommodate other parallel requests such as event-triggered, business event-triggered, and flow-triggered campaigns. * **Space out one-time and periodic campaigns**\ If you are seeing 'FCM Message rate exceeded' a lot in one-time and periodic campaigns, you might be scheduling multiple campaigns that are being sent out at the same time, which is increasing your overall sending speed. Therefore, space out one-time and periodic campaigns. * **Request a rate limit increase from FCM** To check your current limit, go to [Google Cloud console](https://console.cloud.google.com/) > APIs & Services > Firebase Cloud Messaging API > Quotas & System Limits or directly to [FCM Quotas](https://console.cloud.google.com/apis/api/fcm.googleapis.com/quotas) and see the value for Send requests per minute. To request a rate limit increase beyond 600,000 RPM, [contact Firebase Support](https://firebase.google.com/support). # FAQs MoEngage SDKs are already compliant with these changes from FCM. You need not update MoEngage SDK when you switch to the Private key authentication mechanism.\ The Server Key or Auth key is a mechanism to authenticate MoEngage to send requests to FCM on behalf of your account. It works at an account level and not at an end-user level or device level.\ When you switch from Server key to Private key, all requests will be transferred to Auth key mechanism with no impact on the end user or device. Sending messages (including upstream messages) with the FCM XMPP and HTTP legacy APIs was deprecated on June 20, 2023 and **will be removed on June 21, 2024**. Refer to Deprecation of Legacy HTTP API. We strongly recommend the Private key for any request sent to Firebase services as soon as possible. The FCM Server key mechanism will be deprecated on June 21, 2024. After that, FCM may continue to accept requests from the Server key auth mechanism and not deliver the notifications to the devices or it may start rejecting the API requests altogether. In both cases, **your users will no longer receive notifications through FCM**. After you save the settings in the MoEngage dashboard, your account will immediately switch to using the new API to send Android push notifications including ongoing campaigns. You will not see any drops in sending push notifications during the transition. The updated FCM API introduces several improvements, including the adoption of the HTTP v1 protocol and the implementation of short-lived access tokens following the OAuth2 security model, replacing the Server key authentication from the previous version. These tokens enhance security by limiting their usage to approximately one hour, minimising the risk in case they are exposed. With the Private key Auth mechanism, the Firebase Cloud Messaging API has eliminated the bulk sending mechanism and has a default rate limit of 600,000 requests per minute. For more information, refer [here](https://firebase.google.com/support/faq#fcm-depr-rampup). If your account reaches that limit, FCM may drop those notifications. Given bulk notifications are no longer supported, you may see a reduction in campaign sending speed for bulk campaigns such as one-time and periodic campaigns.\ MoEngage has proactively reduced the maximum allowed throttle speed for Push notifications to 500,000 RPM to ensure a single campaign does not breach the project limit. This change will apply to new and existing campaigns. You may still see drops because of multiple campaigns being triggered together. To learn more, refer to changes in [Sending Speed with Private Key Configuration](/android-sdk/push/basic/fcm-authentication#Steps-to-Generate-a-Private-Key). When you set the authentication as a Private key, the changes are accepted immediately and will be used for sending subsequent requests. # Notification Runtime Permissions Source: https://moengage.com/docs/developer-guide/android-sdk/push/basic/notification-runtime-permissions Handle Android 13 notification runtime permissions in your app using the MoEngage SDK. Android 13 (API level 33) and higher supports [runtime permission](https://developer.android.com/guide/topics/permissions/overview#runtime) for sending [non-exempt](https://developer.android.com/develop/ui/views/notifications/notification-permission#exemptions) (including Foreground Services (FGS)) notifications from an app [POST\_NOTIFICATIONS](https://developer.android.com/reference/android/Manifest.permission#POST_NOTIFICATIONS). This change helps users focus on the notifications that are most important to them. Refer to the [official documentation](https://developer.android.com/develop/ui/views/notifications/notification-permission) for more details. The below-mentioned APIs are supported starting MoEngage core Android SDK version **12.3.01** When an application runs on Android 13 and wants to show notifications to the user, it must request the user's notification permission. You have two options: let MoEngage handle permissions for you or handle the notification permission with your code. * MoEngage handles Notification permission. * You just have to call a single line of code mentioned on this page. * You maintain the notification permission logic. * Notify MoEngage SDK if permission to push notifications is granted. We recommend you let MoEngage handle push notification permissions. ## Notify SDK of permission result Once the application requests the user for notification permission notify the SDK of the user response using the below API. *If you are letting MoEngage SDK handle the notification permissions, you should ignore this step.* ```Kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().pushPermissionResponse(applicationContext, isGranted) ``` ```Java Java wrap theme={null} MoEPushHelper.getInstance().pushPermissionResponse(applicationContext, isGranted); ``` ## Update the Permission request count(optional) Once the application requests the user for notification permission, update the SDK of the request attempts.  **Why does the SDK require permission attempt count?** SDK requires the attempt count to accurately track the number of times the permission request was attempted. If the user denies the permission request twice the application/SDK cannot request permission further i.e. if we request permission it would be automatically denied without the user seeing the request dialog. As an SDK we cannot be sure of the number of times the user has denied the permission we try to optimize the calls to request permission based on the attempt count. ```Kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().updatePushPermissionRequestCount(applicationContext, requestCount) ``` ```Java Java wrap theme={null} MoEPushHelper.getInstance().updatePushPermissionRequestCount(applicationContext, requestCount); ``` ## Setup Notification Channels If the application has already taken notification permission from the user call the below API to set up Notification Channels for showing push notifications. ```Kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().setUpNotificationChannels(context) ``` ```Java Java theme={null} MoEPushHelper.getInstance().setUpNotificationChannels(context); ``` ## Let MoEngage SDK handle Notification permission MoEngage SDK provides helper APIs to show the permission request to the end-user or navigate the user to the settings screen for enabling notifications. Use the below API to show the permission request dialog to the user. When using the below API SDK automatically tracks the response, sets up the required notification channel, etc, mentioned above. ```Kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().requestPushPermission(activity) ``` ```Java Java theme={null} MoEPushHelper.getInstance().requestPushPermission(activity); ``` ## Navigate to Notification Settings (situational/optional) Use the below API to show navigate the user to the Notification Settings for the application on the device. *Note*: Below Android 8(API level 26) the user is directed to the Application Info screen of your application. ```Kotlin Kotlin wrap theme={null} MoEPushHelper.getInstance().navigateToSettings(activity) ``` ```Java Java theme={null} MoEPushHelper.getInstance().navigateToSettings(activity); ``` # Push Configuration Source: https://moengage.com/docs/developer-guide/android-sdk/push/basic/push-configuration Configure push notification metadata, icons, and Firebase settings for the MoEngage Android SDK. # Configuring your MoEngage Account * Ensure you have configured the [Firebase](https://firebase.google.com/docs/android/setup) application. * Configure FCM Authorization on the MoEngage Dashboard. For more information, refer to [FCM Authentication](/android-sdk/push/basic/fcm-authentication). * Ensure you add the keys in both the Test and Live environments. ## Adding metadata for push notification Metadata regarding the notification is required to show push notifications where the small icon and large icon drawable are mandatory. For more information about API reference for all the possible options, refer to [NotificationConfig](https://moengage.github.io/android-api-reference/core/com.moengage.core.config/\[android-jvm]-notification-config/index.html). Use the [*configureNotificationMetaData()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-notification-meta-data.html) to transfer the configuration to the SDK. ```Kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "XXXXXXXX") .configureNotificationMetaData(NotificationConfig(R.drawable.small_icon, R.drawable.large_icon)) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```Java Java wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .configureNotificationMetaData(new NotificationConfig(R.drawable.small_icon, R.drawable.large_icon)) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` Ensure that the SDK is initialized with the metadata in the *onCreate()* of the Application class for push notifications to work. **Notification Icon Guidelines** * The notification small icon should be flat, pictured face on, and must be white on a transparent background. * If you do not have the large icon configured for the notification, pass -1 to use the system default. ## Notification Small Icon Density, Size | Density (dp) | Size (px) | | ------------ | --------- | | MDPI | 24x24 | | HDPI | 36x36 | | XHDPI | 48x48 | | XXHDPI | 72x72 | | XXXHDPI | 96x96 | **Critical** Please ensure the small icon is set. If the small icon is not set, notifications will not be displayed. ## Stacking Notifications (optional) By default, Android replaces an old notification with a new one from your application. If you want to show multiple notifications from your app stacked in the notification drawer, you can enable this feature. To enable stacked notifications, set `isMultipleNotificationInDrawerEnabled` to `true` in the `NotificationConfig` during the SDK initialization. Refer to the [notification config](https://moengage.github.io/android-api-reference/core/com.moengage.core.config/\[android-jvm]-notification-config/index.html) for additional options. ```Kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "XXXXXXXX") .configureNotificationMetaData(NotificationConfig(R.drawable.small_icon, R.drawable.large_icon, R.color.notiColor, true)) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```Java Java wrap theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .configureNotificationMetaData(new NotificationConfig(R.drawable.small_icon, R.drawable.large_icon, R.color.notiColor, true) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` If you do not need to set a specific color for the notification, pass -1 to use the system default. # Push token registration and Display Source: https://moengage.com/docs/developer-guide/android-sdk/push/basic/push-token-registration-and-display Set up push token registration and notification display with FCM in the MoEngage Android SDK. You must complete two mandatory steps to get push notifications working. 1. Push token registration - Registration for Push and generating push tokens. 2. Push display - Receiving the Push payload from Firebase Cloud Messaging(FCM) service and showing the notification on the device. We recommend you let MoEngage handle both steps as it eases the integration process also MoEngage SDK has a built-in retry mechanism to handle token registration failure due to FCM downtime or network issues. The SDK also supports cases where your application manages the token registration and receives the notification payload. To support both use cases, this article is broken down into two major sections: * **Push token registration and display by MoEngage SDK** - Integration steps required for MoEngage SDK to handle Push token registration and display. * **Push token registration and payload received by the Application** - Integration steps required for your application to handle Push token registration and receiving notification payload. First, we will look at the integration steps needed if **MoEngage SDK** handles Push token registration and display. Refer to [this section](#Push-display-for-Non-MoEngage-Payloads-optional) for the integration steps required if **the app** handles push token registration and receives the notification payload. # Push token registration and display by MoEngage SDK **Critical** * When the SDK handles token registration, use firebase-messaging **23.0.0** or higher. * At any point, your application manifest file should have only one service with intent filter com.google.firebase.MESSAGING\_EVENT. If there is more than one service, only the first service will receive the callback, and MoEngage SDK might never receive the Push Payload, resulting in poor delivery rates. Add the following code to the manifest file so that MoEngage SDK will receive the notification: ```xml AndroidManifest.xml wrap theme={null} ``` The following steps are optional; use them only if you have the use cases. ## Token Callback - Access to push token (optional) You might want to get access to the push token that MoEngage registered on behalf of your application. When MoEngage SDK handles push registration, it optionally provides a callback to the application whenever a new token is registered or refreshed. To get the token callback, implement the [*TokenAvailableListener*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.listener/%5Bandroid-jvm%5D-token-available-listener/index.html?query=fun%20interface%20TokenAvailableListener) and register for the callback using [*MoEFireBaseHelper.getInstance().addTokenListener()*](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase/-mo-e-fire-base-helper/add-token-listener.html)\_. We recommend you add the callbacks in the ***onCreate()*** of the Application class since these callbacks can be triggered even when the application is in the background. ## Push display for Non-MoEngage Payloads (optional) Your App might want to handle notifications that aren't from MoEngage. If you use the receiver provided by the SDK in your application's manifest file, the SDK provides a callback in case a push payload is received for any other server apart from the MoEngage Platform. To get a callback, implement the [*NonMoEngagePushListener*](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase.listener/-non-mo-engage-push-listener/index.html) and register for the callback using [*MoEFireBaseHelper.getInstance().addNonMoEngagePushListener*](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase/-mo-e-fire-base-helper/add-non-mo-engage-push-listener.html). We recommend you add the callbacks in the ***onCreate()*** of the Application class since these callbacks can be triggered even when the application is in the background. # Push token registration and payload received by the Application Skip this section if already letting MoEngage SDK handle push token registration and display. By default, MoEngage SDK attempts to register for a push token. If your application handles push token registration, you must opt out of MoEngage SDK's token registration. ## How to opt-out of MoEngage Push token registration? To opt out of MoEngage's token registration mechanism, disable token registration using [*configureFCM()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-fcm.html) API while configuring FCM in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) as described ```Kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "XXXXXXXX") .configureNotificationMetaData(NotificationConfig(R.drawable.small_icon, R.drawable.large_icon, R.color.notiColor, null, true, isBuildingBackStackEnabled = false, isLargeIconDisplayEnabled = true)) .configureFcm(FcmConfig(false)) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```Java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .configureNotificationMetaData(new NotificationConfig(R.drawable.small_icon, R.drawable.large_icon, R.color.notiColor, "sound", true, true, true)) .configureFcm(new FcmConfig(false)) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` ## Pass the Push Token To MoEngage SDK Your application must pass the Push Token received from FCM to the MoEngage SDK for the MoEngage platform to send out push notifications to the device.\ Use the [passPushToken()](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase/-mo-e-fire-base-helper/pass-push-token.html) API to pass the push token to the MoEngage SDK. ```Kotlin Kotlin wrap theme={null} MoEFireBaseHelper.getInstance().passPushToken(applicationContext,token) ``` ```Java Java theme={null} MoEFireBaseHelper.getInstance().passPushToken(getApplicationContext(), token); ``` Ensure the token is passed to MoEngage SDK whenever the push token is refreshed and updated on the application. Passing the token on the application update is important for migration to the MoEngage Platform. ## Passing the Push payload to the MoEngage SDK Even though you have your receiver to receive the notification payloads, you must pass messages from MoEngage platform to MoEngage SDK to render push notifications, especially rich push notifications. In that case, pass the payload to MoEngage SDK using the following method. To pass the push payload to the MoEngage SDK call the [*passPushPayload()*](https://moengage.github.io/android-api-reference/moe-push-firebase/com.moengage.firebase/-mo-e-fire-base-helper/pass-push-payload.html) API from the *onMessageReceived()* in the Firebase receiver.\ Before passing the payload to the MoEngage SDK you should check if the payload is from the MoEngage platform using the [*isFromMoengagePlatfrom()*](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase/\[android-jvm]-mo-e-push-helper/is-from-mo-engage-platform.html) helper API provided by the SDK. ```Kotlin Kotlin wrap theme={null} if (MoEPushHelper.getInstance().isFromMoEngagePlatform(remoteMessage.data)){ MoEFireBaseHelper.getInstance().passPushPayload(applicationContext, remoteMessage.data) }else{ // your app's business logic to show notification } ``` ```Java Java theme={null} if (MoEPushHelper.getInstance().isFromMoEngagePlatform(remoteMessage.getData())) { MoEFireBaseHelper.Companion.getInstance().passPushPayload(getApplicationContext(), remoteMessage.getData()); }else{ // your app's business logic to show notification } ```   # Rich Landing A rich landing page can open a web URL inside the app via a push campaign. Irrespective of who handles the push token registration and display, this step is needed to show rich landing pages using the MoEngage platform. The XML code mentioned below is included in the new SDK version, but you can still use it to change the parent activity of MoEActivity if needed. To use a rich landing page, you need to add the below code in the **AndroidManifest.xml** ```XML XML wrap theme={null} ``` | Parameter | Description | | ------------------------- | ------------------------------------------------------------------- | | \[ACTIVITY\_NAME] | Replace with the name you want to appear on your rich landing page. | | \[PARENT\_ACTIVITY\_NAME] | Replace with the parent activity name that you want. | # Device Triggered Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/device-triggered Install the MoEngage realtime-trigger module to enable device-triggered push notifications on Android. # SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:realtime-trigger") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. # Heads Up Notification Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/heads-up-notification Configure heads-up push notifications using Android notification channels in the MoEngage SDK. ## **Overview** **Notification Channel Setup** Heads-up notifications are supported only through Android notification channels. Please refer to the official documentation for the creation of the [notification channels](https://developer.android.com/develop/ui/views/notifications/channels). On Android devices using API levels under 26, the configuration won't be applied, as notification channels that need this setting weren't available until API level 26. The Notification channel should have **IMPORTANCE\_HIGH** for heads-up notifications, and the same channel ID should be configured in the MoEngage dashboard. ## Configuration In MoEngage Android version **13.06.00**, a new flag **isDirectPostingForHeadsUpEnabled** has been added in the **NotificationConfig**. If you are using HeadsUp Notification, we strongly recommend you pass the **isDirectPostingForHeadsUpEnabled** flag as true while initializing SDK. By default, it will be false.  For more information about API reference for all the possible options, refer to [NotificationConfig](https://moengage.github.io/android-api-reference/core/com.moengage.core.config/\[android-jvm]-notification-config/index.html). Use the [*configureNotificationMetaData()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-notification-meta-data.html) to transfer the configuration to the SDK. ```Kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "XXXXXXXX") .configureNotificationMetaData(NotificationConfig(smallIcon = R.drawable.small_icon, largeIcon = R.drawable.large_icon, isDirectPostingForHeadsUpEnabled = true)) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```Java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .configureNotificationMetaData(new NotificationConfig(R.drawable.small_icon,R.drawable.large_icon,R.color.notiColor,isMultipleNotificationEnabled,true)) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` ## HeadsUp Notification Behaviour If **isDirectPostingForHeadsUpEnabled** is true, SDK will use a direct posting mechanism to post Rich content directly if it's a high-priority channel. So the floating heads-up notification view will be shown for 5-8 seconds if it is not interacted with. On Android versions prior to API level 26, the flag will be ignored by default, and it will use the re-posting mechanism by default. Otherwise, if **isDirectPostingForHeadsUpEnabled** is false, it will use the existing reposting mechanism, where text is posted first, and once media assets are downloaded,  rich content is posted. This is to ensure at least some content is shown to the user immediately when the notification is received and to maintain a good impression rate. If this is the case, a heads-up window will get dismissed within few seconds due to reposting. ## Non-Headsup Notification Behaviour For notifications with channel ID having channel importance other than **IMPORTANCE\_HIGH**, SDK will be using the reposting mechanism by default. Please refer to the [user guide](https://help.moengage.com/hc/en-us/articles/34998473340948-Heads-Up-Notifications) to understand more about the heads-up notification behavior and OEM limitations. # Location Triggered Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/location-triggered Set up geofence-based location-triggered push notifications in your Android app with the MoEngage SDK. # Prerequisites To use location triggered (Geofence) push, your app must request the following: * ACCESS\_FINE\_LOCATION * ACCESS\_BACKGROUND\_LOCATION if your app targets Android 10 (API level 29) or later. For location triggered push to work, ensure your Application has the following enabled: Location permission, Play Services location library, and device's location. For more information, refer to [Android Request Geofences](https://developer.android.com/training/location/geofencing#RequestGeofences). # SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:geofence") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. # Configure Geofence By default, the geofence feature is not enabled. To enable the feature, call the below API. ```kotlin Kotlin wrap theme={null} MoEGeofenceHelper.getInstance().startGeofenceMonitoring(context) ``` ```java Java theme={null} MoEGeofenceHelper.getInstance().startGeofenceMonitoring(context); ``` At any time if you want to stop the geofence monitoring or feature, use the below API. This API will remove the existing geofences. ```kotlin Kotlin wrap theme={null} MoEGeofenceHelper.getInstance().stopGeofenceMonitoring(context) ``` ```java Java theme={null} MoEGeofenceHelper.getInstance().stopGeofenceMonitoring(context); ``` ## Callback MoEngage SDK optionally notifies the application whenever a Geo-Fence is triggered. If required, the application can consume the trigger and ask the SDK not to process it. Alternatively, the application can just use the callback for logging/analytical purposes and let MoEngage process the trigger. For more information about implementing callback in the application using [*OnGeofenceHitListener*](https://moengage.github.io/android-api-reference/geofence/com.moengage.geofence.listener/-on-geofence-hit-listener/index.html). Register the listener in the Application class *onCreate()* using [*MoEGeofenceHelper.getInstance().addListener()*](https://moengage.github.io/android-api-reference/geofence/com.moengage.geofence/-mo-e-geofence-helper/add-listener.html). # Notification Center Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/notification-center Add a notification center to your Android app to display push notification history using MoEngage SDK. # Overview The Notification Center shows your push notification history, allowing you to provide an option for the end-user to scroll back and see what they have missed. MoEngage provides out-of-box inbox support with a fully customizable default UI and also provides an option to build your own Notification Center.  # Using MoEngage's default Notification Center ## SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:inbox-ui") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them..  ## Adding the default Notification Center to your app To use the default Notification Center UI you can either launch the [Activity](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-activity/index.html) provided by the SDK or add the [Fragment](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-fragment/index.html) provided by the SDK. ### Use Activity The activity is already declared in the SDK's manifest file and can be inflated using the below code. ```kotlin Kotlin wrap theme={null} //launching the default InboxActivity val intent = Intent(this, InboxActivity::class.java) startActivity(intent) ``` ```java Java theme={null} Intent intent = new Intent(this, InboxActivity.class); startActivity(intent); ``` ### Use Fragment You can embed [*InboxFragment*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-fragment/index.html) provided by the SDK in your app's activity. For information on how to add a Fragment to an Activity, refer to [Google documentation on Fragments](https://developer.android.com/guide/fragments). # Adding parent Activity to the inbox. Optionally if you want to define the parent activity for the Inbox then use the below code. Replace ***\[PARENT\_ACTIVITY\_NAME]*** with the name of the parent activity. ```xml XML wrap theme={null} //launching the default InboxActivity val intent = Intent(this, InboxActivity::class.java) startActivity(intent) ``` # Customizing Default Notification Center SDK provides a certain set of UI customization options. The [InboxActivity](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-activity/index.html) is already in the SDK's manifest file, if a change in label/theme of the default activity is required the activity should be declared again in your app's manifest file and override the attributes. ## Activity Label customization The default label for the Inbox Activity is ***Notification Inbox***, which you can override by declaring the ***moe\_inbox\_notification\_title*** in the ***strings.xml***  of your application. ```xml strings.xml wrap theme={null} [LABEL] ``` ### Activity theme To customize the theme, you can either re-declare the activity in your app's manifest and provide the desired theme, or you can override the SDK defaults as described below. The default theme applied to ***InboxActivity*** is ***MoEInboxTheme.NoActionBar***. You can declare a theme with the same name in the application's ***style.xml*** or ***themes.xml*** or equivalent file. Below is the definition of the default theme ```xml styles.xml wrap theme={null} ``` To customize the theme, override any of the color attributes by defining the color attributes with the same name in your application's **colors.xml** file. ```xml color.xml wrap theme={null} {/* Theme customisation */} #1C64D0 @color/moe_black @color/moe_white @color/moe_black ``` For example, if you want to customize the primary dark color define ***moe\_inbox\_color\_primary\_dark***  in your app's **colors.xml** as shown below. ```xml XML wrap theme={null} [YOUR_COLOR] ``` Similarly, you can customize * Toolbar Style * Message Text Appearance * Header * Message * Timestamp * Scrollbar style * Empty Notification Center style You can override the below SDK's default attributes to customize the theme. ```xml XML wrap theme={null} {/* Toolbar Text Style */} {/* Header style */} {/* Message style */} {/* List Item Separator style */} {/* Timestamp Style */} {/* Empty List Style */} {/* Scrollbar style */} ``` ## InboxAdapter Customization You can override [*InboxAdapter*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.adapter/-inbox-adapter/index.html) to customize the look and feel of the notification Items. In case of using a custom [*InboxAdapter*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.adapter/-inbox-adapter/index.html), the app should make sure to invoke [*InboxListAdapater.onItemClicked()*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.adapter/-inbox-list-adapter/on-item-clicked.html) on the message item click for the SDK to handle the notification click action; otherwise, the click event will not be tracked, and the on click action will not be executed. Once your custom InboxAdapter is ready, set the custom Adapter in [MoEInboxUiHelper](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui/-mo-e-inbox-ui-helper/index.html) before launching the [InboxActivity](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-activity/index.html). ```kotlin Kotlin wrap theme={null} MoEInboxUiHelper.getInstance().setInboxAdapter(InboxCustomAdapter()) ``` ## Advanced customization options 1. Deleting Notification from Notification Center\ You can delete a particular notification from Notification Center by calling [deleteItem(](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.adapter/-inbox-list-adapter/delete-item.html)**)**. ```kotlin Kotlin wrap theme={null} public fun onBind(position: Int, inboxMessage: InboxMessage, inboxListAdapter: InboxListAdapter) { deleteButton.setOnClickListener{ //Call `deleteItem` method to remove Notification //with item's position and the `InboxMessage` object. inboxListAdapter.deleteItem(position, inboxMessage) } } ``` ```java Java theme={null} public void onBind(int position, InboxMessage inboxMessage, InboxListAdapter inboxListAdapter) { deleteButton.setOnClickListener(v -> { //Call `deleteItem` method to remove Notification //with item's position and the `InboxMessage` object. inboxListAdapter.deleteItem(position, inboxMessage); }); } ``` Now, your Notification will get deleted from Notification Center, and Notification Center will get updated. 2. Custom notification item click handling In case you are using the default Notification Center or using the [*InboxFragment*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.view/-inbox-fragment/index.html) in your app without overriding [*InboxAdapter*](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.adapter/-inbox-adapter/index.html), by default, the SDK will handle the notification click action, but you can opt to handle the click action in your app by setting [OnMessageClickListener](https://moengage.github.io/android-api-reference/inbox-ui/com.moengage.inbox.ui.listener/-on-message-click-listener/index.html). ```kotlin Kotlin wrap theme={null} //set the Message click listener MoEInboxUiHelper.getInstance().setOnMessageClickListener(listener) //Remove the Message click listener MoEInboxUiHelper.getInstance().setOnMessageClickListener(null) ``` ```java Java theme={null} //set the Message click listener MoEInboxUiHelper.getInstance().setOnMessageClickListener(listener); //Remove the Message click listener MoEInboxUiHelper.getInstance().setOnMessageClickListener(null); ``` # Self Handled Notification Center MoEngage SDK provides helper APIs to fetch the relevant inbox data to display, track events, delete messages, etc. that can be used to build your Notification Centre. ![MavenBadge](https://img.shields.io/maven-central/v/com.moengage/inbox-core) ## SDK Installation ### Installing using Catalog Integration using a Version Catalog is the recommended way of integration. Once you have configured the catalog, add the dependency in the ***app/build.gradle*** file as shown below ```auto build.gradle wrap theme={null} dependencies { ... implementation(moengage.inboxCore) } ``` Alternatively, you can add the dependency using Artifact ID as described in [Installation using Artifact ID](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id#In-App). However, installation using Catalog ID is the recommended approach as installing using Artifact ID may lead to version mismatch if mapped incorrectly. # Build Your Notification Center The below helper APIs can be used to build your own Notification Center. For more information on available helper APIs refer [here](https://moengage.github.io/android-api-reference/inbox-core/com.moengage.inbox.core/-mo-e-inbox-helper/index.html). ## Get all messages ```kotlin Kotlin wrap theme={null} // synchronous API should not be called on the main thread MoEInboxHelper.getInstance().fetchAllMessages(context) // asynchronous API, where listener is an instance of `OnMessagesAvailableListener` MoEInboxHelper.getInstance().fetchAllMessagesAsync(applicationContext, listener) ``` ```java Java theme={null} // synchronous API should not be called on the main thread MoEInboxHelper.getInstance().fetchAllMessages(context); // asynchronous API, where listener is an instance of `OnMessagesAvailableListener` MoEInboxHelper.getInstance().fetchAllMessagesAsync(applicationContext, listener); ``` ## Get UnClicked Notifications count ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().getUnClickedMessagesCount(applicationContext) ``` ```java Java theme={null} MoEInboxHelper.getInstance().getUnClickedMessagesCount(applicationContext) ``` ## Track Inbox Notification Clicks ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().trackMessageClicked(context, inboxMessage) ``` ```java Java theme={null} MoEInboxHelper.getInstance().trackMessageClicked(context, inboxMessage); ``` ## Delete Inbox Message ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().deleteMessage(context, inboxMessage) ``` ```java Java theme={null} MoEInboxHelper.getInstance().deleteMessage(context, inboxMessage); ``` ## Delete All Inbox Message This feature requires a minimum catalog version **4.5.0**. ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().deleteAllMessages(context) ``` ```java Java theme={null} MoEInboxHelper.getInstance().deleteAllMessages(context); ``` ## Check if the notification has a coupon code ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().hasCouponCode(inboxMessage) ``` ```java Java theme={null} MoEInboxHelper.getInstance().hasCouponCode(inboxMessage); ``` ## Get coupon code ```kotlin Kotlin wrap theme={null} MoEInboxHelper.getInstance().getCouponCode(inboxMessage); ``` ```java Java theme={null} MoEInboxHelper.getInstance().getCouponCode(inboxMessage); ``` Refer to [API reference](https://moengage.github.io/android-api-reference/inbox-core/com.moengage.inbox.core/-mo-e-inbox-helper/index.html) for more details. # Configuring HMS Push Kit Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-amp-plus/configuring-hms-push-kit Configure Huawei HMS Push Kit in your Android app for MoEngage push notification delivery. * Ensure that you have configured Push Kit on your application.\ For more information, refer to [HMS Push Kit documentation](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/service-introduction-0000001050040060). * Ensure that you configure MoEngage SDK for receiving push notifications. # SDK Installation ## Installing Using BOM Integration using BOM is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document to configure BOM if not done already. Once you have configured the BOM add the dependency in the ***app/build.gradle*** file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:hms-pushkit") } ``` Alternatively, you can add the dependency using Artifact ID as described in [Installation using Artifact ID](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id#In-App). However, installation using BOM is the recommended approach as installing using Artifact ID may lead to version mismatch if mapped incorrectly.  # Push Token Management When using MoEngage SDK, you can either register for token and pass it on to the MoEngage SDK or simply let MoEngage SDK register for Push Token. ## Token Registration Handled by Application If your application is registering for Push Notification, use the below API to pass the Push token to the MoEngage SDK. ```kotlin Kotlin wrap theme={null} MoEPushKitHelper.getInstance().passPushToken(context, token) ``` ```java Java theme={null} MoEPushKitHelper.getInstance().passPushToken(context, token); ``` ## Token Registration Handled by MoEngage By default, the MoEngage SDK does not register for push tokens. You can enable the token registration using the [configurePushKit()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-push-kit.html) API in the [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) while initializing the SDK ```kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "XXXXXXXX") .configurePushKit(PushKitConfig(true)) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXX") .configurePushKit(new PushKitConfig(true)) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` Add the below Service in your application's Manifest file. ```xml AndroidManifest.xml wrap theme={null} > ``` When MoEngage SDK handles push registration, it optionally provides a callback to the Application whenever a new token is registered, or the token is refreshed.\ An application can get this callback by implementing the [TokenAvailableListener](https://moengage.github.io/android-api-reference/pushbase/com.moengage.pushbase.listener/-token-available-listener/index.html) interface and registering the listener using [MoEPushKitHelper.getInstance().addTokenListener()](https://moengage.github.io/android-api-reference/hms-pushkit/com.moengage.hms.pushkit/-mo-e-push-kit-helper/add-token-listener.html) API. To use Push Kit, you need to update the *moe-android-sdk* to 10.3.00 or above. # Configure Your Account on MoEngage Now you have set up Huawei Push on MoEngage SDK. Proceed to [configuring Huawei Push on MoEngage dashboard](/android-sdk/push/optional/push-amp-plus/configuring-huawei-push-on-mo-engage). # Configuring Huawei Push on MoEngage Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-amp-plus/configuring-huawei-push-on-mo-engage Set up Huawei Push Kit callback URLs and HTTPS certificates on the MoEngage Dashboard. # Developer Guide Please make sure that you have set up Push Kit on your application. To configure, use the following: * [Introduction to HMS Push Kit](https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/push-introduction). * [Push Receipt](https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/push-receipt#receiptright). # MoEngage Callback URL | New DataCenter | New Callback URL | Old Callback URL | | -------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | Data Center 1 | [https://api-01.moengage.com/hmspush/dlr](https://api-01.moengage.com/hmspush/dlr) | [https://smsapi.moengage.com/hmspush/dlr](https://smsapi.moengage.com/hmspush/dlr) | | Data Center 2 | [https://api-02.moengage.com/hmspush/dlr](https://api-02.moengage.com/hmspush/dlr) | [https://smsapi.moengage.com/hmspush/dlr](https://smsapi.moengage.com/hmspush/dlr) | | Data Center 3 | [https://api-03.moengage.com/hmspush/dlr](https://api-03.moengage.com/hmspush/dlr) | [https://smsapi.moengage.com/hmspush/dlr](https://smsapi.moengage.com/hmspush/dlr) | | Data Center 4 | [https://api-04.moengage.com/hmspush/dlr](https://api-04.moengage.com/hmspush/dlr) | NA | Update the URL in the callback address while enabling the recipient. ## HTTPS Certificate for MoEngage callback URL * Select data storage other than the China region when enabling callback receipt. * Use the following script to generate the HTTPS certificate while enabling the recipient. For more information, refer to [Push Receipt](https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/push-receipt#receiptright). ```python HTTPS certificate generation using Python wrap theme={null} import ssl print(ssl.get_server_certificate(('dashboard-01.moengage.com', 443))) ``` # Configuring Huawei Push To configure Huawei on the MoEngage dashboard: 1. Navigate to **Settings > Channels > Push > App Push > Huawei (Push Amp+)**. 2. Select Huawei (Push Amp+) in the Platforms available on the menu at the top. Mceclip0(1) ## App ID Get the App ID from the [Huawei Developer Console](https://developer.huawei.com/) by navigating to\ **Login > AppGallery Connect > My Apps > Select Your App > Distribute > App Information** Appsecret ## App Secret Get the App ID from the [Huawei Developer Console](https://developer.huawei.com/) by navigating to\ **Login > AppGallery Connect > My Apps > Select Your App > Distribute > App Information** Appsecret1 ## Package Name The package name for an application is the unique identifier through which the play store recognizes the application. You can find the package of your application in the **build.gradle** file of your application module. Packagename If you have different package names for debug build and signed build configure the package names accordingly in the Test/Live Environment. ## Small Icon Path As an important part of a notification message, a notification icon is used to identify the content and type of the message. To ensure a consistent user experience, *HUAWEI Push Kit notification icons* inherit the styles of native Android notification icons. In other words, a notification icon on the notification bar is displayed in a solid color and the notification icon on the status bar is displayed in black or white. The status bar and notification bar share the same resources. For more information, refer to the [guideline document](https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/push-icon-spec).   Smalliconpath The icon file must be stored in the /res/raw directory of an app. For example, the value **/raw/ic\_launcher** indicates the local icon file **ic\_launcher.xxx** stored in **/res/raw**. Currently, supported file formats include PNG and JPG. # Push AMP Plus Integration Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-amp-plus/push-amp-plus-integration Integrate MoEngage Push Amp+ to improve push notification delivery rates on Android OEM devices. Almost 25-30% of notifications are not delivered because of OEM-related reasons. With Push Amplification+, you can reach these customers and see an immediate uplift in retention rates.\ So, we focused on solving the problem of delivery rates on OEMs and have partnered with OEMs to solve this problem. To ensure we do not add additional bloat into your application we have made different SDKs for each OEM. You can integrate the relevant SDK based on the device share your application has. Refer to the respective OEM-specific services documentation below and integrate the relevant ones in your application. Integration supported are: * [Configuring HMS Push Kit](/android-sdk/push/optional/push-amp-plus/configuring-hms-push-kit) # Steps to Remove Mi SDK Dependency Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-amp-plus/steps-to-remove-mi-sdk-dependency Remove the discontinued Xiaomi Mi Push SDK dependency from your MoEngage Android integration. Due to operational concerns, Xiaomi Corporation has recently notified users about the discontinuation of the Mi Push service beyond Mainland China. You might have already received correspondence regarding this matter.  In this regard, we suggest that our customers remove Mi Push SDK from their apps. The steps to do so are enumerated in this article. ## Step 1: Remove Mi aar 1. Navigate to app --> libs 2. Delete MiPush\_SDK\_Client\*.aar ## Step 2: Remove the Mi receiver from the manifest file Remove the following code from the manifest file. ```xml Remove Mi receiver from the manifest file wrap theme={null} ``` ## Step 3: Remove initialization code Remove the following initialization code from the application. ```kotlin Code to be removed from the application wrap theme={null} MiPushHelper.initialiseMiPush([context], [appKey], [appId], [region]) ``` ## Step 4: Delete the helper files Delete the following helper files: 1. MiPushHelper.kt 2. MiPushReceiver.kt ## Step 5: Remove MoEngage dependency Remove the MoEngage dependency from the dependencies block of the build.gradle as described: 1. MoEngage Catalog - If you are using the MoEngage catalog remove the following dependency: ```kotlin MoEngage Catalog wrap theme={null} implementation(moengage.pushAmpPlus) ``` 2. Artifact ID - If you have added the artifact id remove the following dependency: ```kotlin Artifact ID wrap theme={null} implementation("com.moengage:push-amp:") ``` # Push Amplification Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-amplification Install the MoEngage push-amp module to improve push notification delivery rates on Android. # SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:push-amp") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them. # Push Templates Source: https://moengage.com/docs/developer-guide/android-sdk/push/optional/push-templates Add rich push notification templates with timers and progress bars to your Android app using MoEngage. # SDK Installation ## Installing using BOM Integration using BOM  is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document. Once you have configured the BOM add the dependency in the *app/build.gradle* file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage:rich-notification") } ``` Once the BOM is configured, include the specific MoEngage modules required for the application. \ Note: Version numbers are not required for these dependencies; the BOM automatically manages them.   # Timer with Progress Bar ## Schedule Exact Alarm Permission The SDK uses Alarms to periodically update the progress in the progress bar. Starting Android 12, additional permission is required to use exact alarms. Refer to the [documentation](https://developer.android.com/training/scheduling/alarms#exact) for more details. To support the Timer with Progress Bar template on Android 12 and above devices, add the following permission in your manifest file. ```xml AndroidManifest.xml wrap theme={null} ```   Starting Android 14, the Alarm permission is off by default. So you need to ask for explicit Alarm permission if you want to show Timer notifications apart from adding the previous line in your manifest file. Verify if the permission is already granted and accordingly call the following line to get the Alarm permission from the customer. ```Java Java wrap theme={null} startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM)) ```   If the application does not have the permission above, the Timer with Progress Bar template will not be shown to the user; instead, a backup template will be displayed to the user which will have the Timer but not the progress bar. ## Customization The SDK defines the default color values for the progress bar's background and progress color. These can be customized to suit the application's theme by overriding the values for the below SDK-defined color attributes. To set the custom color in light and dark mode, override the values in **res/values/colors.xml** and **res/values-night/colors.xml**, respectively. ```xml colors.xml wrap theme={null} [YOUR_COLOR] [YOUR_COLOR] ``` # Android Sample App Source: https://moengage.com/docs/developer-guide/android-sdk/sample-app/android-sample-app Explore the MoEngage Android sample app on GitHub as a reference for your SDK integration. **Sample App** The [MoEngage Android Sample application](https://github.com/moengage/Android-Sample) offers a useful reference point for integrating MoEngage into your Android app. ## Next Steps * [SDK Installation](/developer-guide/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) * [Release Checklist](/developer-guide/android-sdk/checklist/release-checklist) # Add-On Security Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/add-on-security Encrypt data stored by the MoEngage Android SDK on device using the encrypted storage module. # Encrypted Storage By default, all the data stored by the SDK on the device is inside the application sandbox. This prevents other applications from accessing the data(both read and write). Though due to compliance standards or any other use cases, you might want additionally encrypt the data stored on the SDK. To enable this encryption you need to * Add the below-listed dependencies in your ***app/build.gradle*** file. * Call the [configureStorageSecurity()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-storage-security.html) to enable the encryption on the [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) object while initializing the SDK ## SDK Installation ### Installing using BOM Integration using BOM is the recommended way of integration; refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document to configure if not done already. Once you have configured the BOM, add the dependency in the ***app/build.gradle*** file as shown below. ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage.security") } ``` Alternatively, you can add the dependency using Artifact ID as described in [Installation using Artifact ID](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id#EncryptedStorage). However, installation using BOM is the recommended approach, as installing using Artifact ID may lead to version mismatch if mapped incorrectly. ## Enabling Encryption You can enable the storage encryption using the [configureStorageSecurity()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-storage-security.html) API in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) while initializing the SDK. ```kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "YOUR_Workspace_ID") .configureStorageSecurity(StorageSecurityConfig(StorageEncryptionConfig(true))) .build() MoEngage.initialise(moEngage) ``` ```java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "YOUR_Workspace_ID") .configureStorageSecurity(new StorageSecurityConfig(new StorageEncryptionConfig(true))) .build(); MoEngage.initialise(moEngage); ``` Note: * If storage encryption is enabled in the initialization without adding the above-mentioned dependencies, SDK wouldn't function i.e. no events/user attributes would be tracked, push notifications would not be shown, etc. * Once storage encryption is enabled and a build is released to production(Play Store or other equivalent stores), you should not disable encryption. Disabling the encryption after the build is released will result in a new user being created in the MoEngage system when the user updates the application. # Encrypted Network Communication By default, we use HTTPS protocol for all requests made from the SDK; HTTPS encrypts the requests by default. MoEngage SDK optionally adds another layer of encryption apart from the encryption done by HTTPS.\ To enable this additional encryption, you need to * Add the below-listed dependencies in your***app/build.gradle*** file. * Call the [configureNetworkRequest()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-network-request.html) on the [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) object while initializing the SDK ## SDK Installation ***If you have enabled Storage encryption, you can skip the installation step and jump to the Enabling Encryption step.*** ### Installing using BOM Integration using BOM is the recommended way of integration, refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document to configure BOM if not done already. Once you have configured the BOM add the dependency in the ***app/build.gradle*** file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage.security") } ``` Alternatively, you can add the dependency using Artifact ID as described in [Installation using Artifact ID](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id#Push-Templates). However, installation using BOM is the recommended approach, as installing using Artifact ID may lead to version mismatch if mapped incorrectly. ## Enabling Encryption You can enable the network encryption using the [configureNetworkRequest()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-network-request.html) API in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) while initializing the SDK. ### Fetch the keys The key is available on the dashboard. Go to **Settings -> APIs -> API Keys and** copy the **SDK encryption key** for the Test and Live environments (Note: Test and Live environments have separate keys and only the key of the current selected environment will be accessible). Fetchthekeys ### Configure Network Request ```kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "YOUR_Workspace_ID") .configureNetworkRequest(NetworkRequestConfig(NetworkDataSecurityConfig(true, "YOUR_TEST_ENVIRONMENT_ENCRYPTION_KEY", "YOUR_LIVE_ENVIRONMENT_ENCRYPTION_KEY"))) .build() MoEngage.initialise(moEngage) ``` ```java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "YOUR_Workspace_ID") .configureNetworkRequest(new NetworkRequestConfig(new NetworkDataSecurityConfig(true, "YOUR_TEST_ENVIRONMENT_ENCRYPTION_KEY", "YOUR_LIVE_ENVIRONMENT_ENCRYPTION_KEY"))) .build(); MoEngage.initialise(moEngage); ``` ***Note:*** When using encrypted network communication, we strongly recommend you enable Storage encryption as well. # Network Request Authorization To enable the network request authorization you need to * Add the below-listed dependencies in your***app/build.gradle*** file. * Call the [configureNetworkRequest()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-network-request.html) to enable the authorization on the [MoEngage.Builder](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) object while initializing the SDK ## SDK Installation ***If you have enabled Storage encryption or Encrypted Network Communication, you can skip the installation step and jump to the Enabling Authorization step.*** ### Installing using BOM Integration using BOM is the recommended way of integration, refer to the [Install Using BOM](/android-sdk/sdk-integration/basic-integration/Install-Using-BOM) document to configure BOM if not done already. Once you have configured the BOM add the dependency in the ***app/build.gradle*** file as shown below ```Groovy build.gradle wrap theme={null} dependencies { ... implementation("com.moengage.security") } ``` Alternatively, you can add the dependency using Artifact ID as described in [Installation using Artifact ID](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id#Device-Triggered). However, installation using BOM is the recommended approach, as installing using Artifact ID may lead to version mismatch if mapped incorrectly. ## Enabling Authorization You can enable the network authorization using the [configureNetworkRequest()](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/configure-network-request.html) API in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html) while initializing the SDK. ```kotlin Kotlin wrap theme={null} val moEngage = MoEngage.Builder(this, "YOUR_Workspace_ID", ) .configureNetworkRequest(NetworkRequestConfig(NetworkAuthorizationConfig(true))) .build() MoEngage.initialise(moEngage) ``` ```java Java theme={null} MoEngage moEngage = new MoEngage.Builder(this, "YOUR_Workspace_ID", ) .configureNetworkRequest(new NetworkRequestConfig(new NetworkAuthorizationConfig(true))) .build(); MoEngage.initialise(moEngage); ``` Adding the above dependency and enabling the flag isn't enough for this feature to work; there is some additional configuration required on our side to enable this feature completely. In case you want to use this feature, reach out to your account manager or the MoEngage Support team. # Custom Proxy Domain - Android Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/custom-proxy-domain-android Route MoEngage SDK traffic through your own subdomain to bypass ad blockers on Android. In today's privacy-focused digital landscape, many users employ ad blockers or private DNS services. These tools often block network requests to known third-party domains, including analytics and engagement platforms. When these requests are blocked, you lose critical data visibility, and your users may not receive in-app messages or push notifications. To ensure reliable campaign delivery, MoEngage offers the **Custom Proxy Domain** feature. This allows you to route MoEngage SDK traffic through a subdomain of your own primary domain (e.g., `data.yourcompany.com`). Because the traffic appears as first-party communication, it bypasses common ad-blocking lists. ## Onboarding Process Setting up a Custom Proxy Domain requires a one-time DNS delegation process between your team and MoEngage. Before updating your SDK code, you must complete the DNS delegation setup. For a detailed guide on picking a domain and configuring NS records, refer to [DNS Delegation](https://help.moengage.com/hc/en-us/articles/45199793953300-DNS-Delegation-for-Custom-Subdomains). ### Step 1: Choose a Subdomain Select a subdomain that is short and does not contain keywords typically flagged by filters (for example, avoid "tracking", "ads", or "moengage"). ### Step 2: Request DNS Delegation Reach out to your MoEngage Customer Success Manager (CSM) or [raise a support ticket](https://help.moengage.com) to initiate the request. Provide your chosen subdomain. ### Step 3: Configure NS Records MoEngage will provide you with four Name Server (NS) records. You must add these records to your DNS provider's configuration for the chosen subdomain. ## Implementation Once the DNS delegation is verified, update your SDK initialization logic. The SDK will dynamically rewrite all MoEngage endpoints (API calls and CDN assets) to use your custom proxy domain. ### Update MoEngage Configuration ```kotlin Kotlin wrap theme={null} import com.moengage.core.DataCenter import com.moengage.core.MoEngage import com.moengage.core.config.DomainConfig import com.moengage.core.config.NetworkRequestConfig val moEngage = MoEngage.Builder(application, "YOUR_Workspace_ID", DataCenter.DATA_CENTER_X) .configureNetworkRequest( NetworkRequestConfig(DomainConfig("CUSTOM_DOMAIN")) ) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```java Java theme={null} import com.moengage.core.DataCenter; import com.moengage.core.MoEngage; import com.moengage.core.config.DomainConfig; import com.moengage.core.config.NetworkRequestConfig; MoEngage moEngage = new MoEngage.Builder(this, "YOUR_Workspace_ID", DataCenter.DATA_CENTER_X) .configureNetworkRequest(new NetworkRequestConfig(new DomainConfig("CUSTOM_DOMAIN"))) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` ## Best Practices and Validation 1. **Domain Selection:** Keep your subdomain string short (5-8 characters). 2. **Network Logs:** Verify that requests start with your custom subdomain (e.g., `sdk-01.data.example.com`). 3. **Asset Loading:** Ensure images in campaigns load correctly. # Installing SDK using Artifact Id Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id Install MoEngage Android SDK modules individually using their Maven Central artifact IDs. We recommend integrating the MoEngage BOM  for easier dependency management. Refer to the [documentation](/sdk-integration/basic-integration/Install-Using-BOM) to know more. # SDK Versions | Artifact Name | Artifact Id | Version | | -------------------------------- | ----------------- | ------- | | Core | moe-android-sdk | | | Self-Handled Cards | cards-core | | | Default Cards | cards-ui | | | Encrypted Storage | encrypted-storage | | | Geofence | geofence | | | HMS Pushkit | hms-pushkit | | | InApp | inapp | | | Self-Handled Notification Center | inbox-core | | | Default Notification Center | inbox-ui | | | PushAmp | push-amp | | | PushAmpPlus | push-amp-plus | | | Device Triggered | realtime-trigger | | | Push Templates | rich-notification | | | Security | security | | # SDK Installation Add the following dependency in the ***app/build.gradle(.kts)*** file to integrate the required modules. Make sure to replace **\$sdkVersion** with the appropriate SDK version ## Core ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:moe-android-sdk:$sdkVersion") } ``` ## Self-Handled Cards ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:cards-core:$sdkVersion") } ``` ## MoEngage's Default Cards ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:cards-ui:$sdkVersion") } ``` ## Encrypted Storage ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:encrypted-storage:$sdkVersion") } ``` ## Geofence ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:geofence:$sdkVersion") } ``` ## HMS Pushkit ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:hms-pushkit:$sdkVersion") } ``` ## InApp ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:inapp:$sdkVersion") } ``` ## Self-Handled Notification Center ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:inbox-core:$sdkVersion") } ``` ## MoEngage's default Notification Center ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:inbox-ui:$sdkVersion") } ``` ## Push Amplification ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:push-amp:$sdkVersion") } ``` ## PushAmpPlus ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:push-amp-plus:$sdkVersion") } ``` ## Device Triggered ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:realtime-trigger:$sdkVersion") } ``` ## Push Templates ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:rich-notification:$sdkVersion") } ``` ## Security ```Kotlin build.gradle(.kts) wrap theme={null} dependencies { ... implementation("com.moengage:security:$sdkVersion") } ``` # JWT Authentication Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/jwt-authentication Secure your MoEngage data collection by implementing JWT authentication in your Android app. ## Overview JWT (JSON Web Token) authentication is a standard method for securely verifying user identity. By implementing JWT authentication, you add a critical layer of security to your data collection process with MoEngage. The feature ensures that the data sent on behalf of your identified users is authentic and is not tampered with. This security is achieved by requiring a token that is cryptographically signed by your own server, which prevents unauthorized users from impersonating your legitimate users. Before you begin the implementation, ensure you meet the following requirements: * Your application must use the MoEngage Android SDK version **14.04.00** or higher to access the JWT authentication feature. * You must have access to your MoEngage dashboard to manage public keys and configure the feature's enforcement settings. The following diagram illustrates the interaction between your application, your server, the MoEngage SDK, and the MoEngage server: Nextttt(1) ## Integration Perform the following to integrate JWT authentication into your Android application: ### Step 1: Enable JWT Authentication You can enable JWT authentication during [SDK initialization](/android-sdk/sdk-integration/basic-integration/sdk-initialization) by configuring the ***NetworkAuthorizationConfig*** property on the ***MoEngage.Builder*** object. ```kotlin Kotlin wrap theme={null} val builder = MoEngage.Builder(application, , ) .configureNetworkRequest(NetworkRequestConfig(networkAuthorizationConfig = NetworkAuthorizationConfig(isJwtEnabled = true))) MoEngage.initialiseDefaultInstance(builder.build()) ``` ```java Java theme={null} MoEngage.Builder builder = new MoEngage.Builder(application, , ) .configureNetworkRequest(new NetworkRequestConfig(new NetworkAuthorizationConfig(true))); MoEngage.initialiseDefaultInstance(builder.build()); ``` ### Step 2: Pass the JWT to the SDK Your application is responsible for managing the JWT lifecycle. The recommended flow is to fetch a token upon user login and pass the token to the SDK. You should also check if the token has expired on subsequent app launches and fetch a new one if necessary.  Use the [***MoECoreHelper.passAuthenticationDetails()***](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-e-core-helper/pass-authentication-details.html) to provide the token to the SDK. ```kotlin Kotlin wrap theme={null} val data = AuthenticationData.Jwt(, ) MoECoreHelper.passAuthenticationDetails(context, data) ``` ```java Java theme={null} AuthenticationData data = new AuthenticationData.Jwt(, ); MoECoreHelper.INSTANCE.passAuthenticationDetails(application.getApplicationContext(), data); ``` ### Step 3: Handle Authentication Errors To handle token validation errors that the MoEngage server returns, you must register an error listener. The SDK invokes this listener when an authentication error occurs, which allows your application to fetch and provide a new token. ```kotlin Kotlin wrap theme={null} val authErrorListener = OnAuthenticationError { error - when (error.data) { is ErrorData.Jwt - { // Handle JWT authentication error val errorData = error.data as ErrorData.Jwt val jwtError = errorData.code val message = errorData.message // Take appropriate action based on the jwtError } } } // Register listener after SDK initialization MoECoreHelper.registerAuthenticationListener(authErrorListener) ``` ```java Java theme={null} OnAuthenticationError errorListener = new OnAuthenticationError() { @Override public void onError(@NonNull AuthenticationError error) { switch (error.getType()) { case JWT: ErrorData.Jwt jwtError = (ErrorData.Jwt) error.getData(); // Handle JWT error JwtError jwtErrorType = jwtError.getCode(); String message = jwtError.getMessage(); // Take action based on jwtErrorType break; } } }; // Register listener after SDK initialization MoECoreHelper.INSTANCE.registerAuthenticationListener(errorListener); ``` ### Step 4: Handle Authentication Errors Register the [***OnAuthenticationError***](https://moengage.github.io/android-api-reference/core/com.moengage.core.model.authentication/\[android-jvm]-on-authentication-error/index.html) listener in a global scope, such as the ***onCreate()*** of your Application class, to ensure your application always receives callbacks. ```kotlin Kotlin wrap theme={null} MoECoreHelper.registerAuthenticationListener(authErrorListener) ``` ```java Java theme={null} MoECoreHelper.INSTANCE.registerAuthenticationListener(errorListener); ``` * If an API request fails due to an authentication error, the SDK will not retry the request until your application provides a new token. * After 10 consecutive authentication failures in a single session, the SDK will stop attempting to sync data until the next session begins. This counter resets after any successful sync. * Upon user logout, if a data sync fails due to a JWT error, the pending data will be deleted, and no retry will be attempted. # Network Security Configuration Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/network-security-configuration Whitelist MoEngage SDK domains in your custom Android network security configuration. This section is only required if you have a custom Network Security Configuration in your application. If your application has a network security configuration that whitelists domains to which your application can send data to whitelist the below domains based on the MoEngage Data Center you have selected while integrating the SDK. | Data Center | Host | | --------------- | ------------------- | | DATA\_CENTER\_1 | sdk-01.moengage.com | | DATA\_CENTER\_2 | sdk-02.moengage.com | | DATA\_CENTER\_3 | sdk-03.moengage.com | | DATA\_CENTER\_4 | sdk-04.moengage.com | | DATA\_CENTER\_5 | sdk-05.moengage.com | | DATA\_CENTER\_6 | sdk-06.moengage.com | By default, the SDK sends the data to *DATA\_CENTER\_1*. In case, you have not configured any data center while initializing the SDK whitelist the host corresponding to *DATA\_CENTER\_1* # SDK Configuration Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/advanced-or-optional/sdk-configuration Review the MoEngage Android SDK build configuration requirements and supported API levels. Android SDK configuration uses the build configuration and library dependencies. # Build Configuration | Configuration | API Level | | ----------------------------- | --------- | | Target SDK Version | 35 | | Compile SDK Version | 35 | | Minimum SDK Version | 23 | | Kotlin Version | 1.9.23 | | Android Gradle Plugin Version | 8.7.3 | Refer to the [API level to code name mapping](https://source.android.com/setup/start/build-numbers) to get the version name. # Library Dependency The SDK is complied using the described version but the versions are modified by the application at runtime. SDK is compiled with the following libraries: ```groovy Groovy wrap theme={null} androidx.core:core:1.15.0 androidx.appcompat:appcompat:1.7.0 androidx.lifecycle:lifecycle-process:2.8.7 ```   The build configuration is available only for the current SDK version. If you are using an older version of the SDK and want to know the build configuration, contact MoEngage support or contact your Account Manager. # Install Using BOM Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/basic-integration/Install-Using-BOM Use the MoEngage Bill of Materials to manage compatible Android SDK module versions. **Information** You can now get notified whenever MoEngage releases a new version of the Android Native SDK. For more information, refer to [Subscribe to MoEngage SDK Releases](/release-notes/subscribe-to-moengage-sdk-releases/subscribe-to-mo-engage-sdk-releases). ## Overview Starting from Android SDK core version [14.04.03](/release-notes/android-sdk/2025-1#11th-December-2025) and later, MoEngage recommends using the Bill of Materials (BOM) to integrate the Android SDK. By defining a single BOM version, you ensure that all MoEngage modules, such as Push Kit, Rich Media, and Geofence, automatically use compatible versions. BOM simplifies dependency management, prevents version conflicts, and eliminates the need to manually track version numbers for each individual artifact. ## Add the BOM to your application To integrate the BOM, add the `android-bom` dependency to the application-level `build.gradle` file. The version number is specified only in this dependency. V(1) ```kotlin build.gradle.kts (Kotlin) wrap theme={null} dependencies { // Import the MoEngage BOM implementation(platform("com.moengage:android-bom:")) } ``` Replace the `` with the relevant version number. For more information on BOM versions, refer to the [Android SDK release notes](/release-notes/android-sdk/). ## Add MoEngage Modules Once the BOM is configured, include the specific MoEngage modules required for the application.\ **Note:** Version numbers are not required for these dependencies; the BOM automatically manages them. ```kotlin build.gradle.kts (Kotlin) wrap theme={null} dependencies { // ------------------------------------------------- // OPTIONAL MODULES (Add based on required features) // ------------------------------------------------- // Cards Core - Required if using Cards Core APIs directly implementation("com.moengage:cards-core") // Cards UI - Required for Cards (feed) UI implementation("com.moengage:cards-ui") // Geofence - Required for Geofence-based campaigns implementation("com.moengage:geofence") // HMS Push Kit - Required for Huawei Push Notifications implementation("com.moengage:hms-pushkit") // InApp - Required for In-App Messaging implementation("com.moengage:inapp") // Inbox Core - Required if using Inbox Core APIs directly implementation("com.moengage:inbox-core") // Inbox UI - Required for Notification Center (Inbox) UI implementation("com.moengage:inbox-ui") // Push Amp - Required for Push Amplification implementation("com.moengage:push-amp") // Real Time Trigger - Required for device-triggered campaigns implementation("com.moengage:realtime-trigger") // Rich Notification - Required for Push Templates implementation("com.moengage:rich-notification") // Security - Required for Security features, for example; storage encryption implementation("com.moengage:security") } ``` **Info** While MoEngage strongly recommends using the BOM for seamless dependency management, you can opt to manually configure versions for each artifact. If you choose this approach, you must ensure that the versions of all integrated modules are compatible with one another. To find the latest versions and compatible artifact combinations, please refer to the [Installing SDK using Artifact Id](/android-sdk/sdk-integration/advanced-or-optional/installing-sdk-using-artifact-id). ## Add Androidx Libraries The SDK depends on a few Androidx libraries for its functioning. Add the below Androidx libraries in your application if not done already. ```groovy Groovy wrap theme={null} implementation("androidx.core:core:1.15.0") implementation("androidx.appcompat:appcompat:1.7.1") implementation("androidx.lifecycle:lifecycle-process:2.8.7") ``` The MoEngage SDK depends on the **lifecycle-process** library for a few key features to work and the latest version of **lifecycle-process** depends on the **androidx.startup:startup-runtime** library. Hence do not remove the **InitializationProvider** component from the manifest. When adding other Initializers using the **startup-runtime** ensure the Initializer for **lifecycle-process** library is also added. Refer to the [documentation](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.4.0) to know how to add the Initializer. ## Impact of using BOM Using the BOM does not increase the application size. It functions strictly as a version manager to ensure compatibility. Only the specific modules included in the `dependencies` block (e.g., `push-kit`, `android-sdk`) are bundled into the application. ## Why use BOM? * **Simplified Versioning:** Eliminates the need to manage individual artifact versions. Updating the BOM version updates the entire integration. * **Compatibility:** The BOM ensures that all integrated modules work efficiently together, preventing runtime crashes caused by mismatched library versions. * **Cleaner Configuration:** Maintains a clean `build.gradle` file with a single source of truth for the SDK version. # Configuring Build Settings Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/basic-integration/configuring-build-settings Configure your Android project build settings by adding the Maven repository and enabling Java 8. ## Add Maven Repository Add `mavenCentral()` repository in the project-level `build.gradle` file. ```Groovy Groovy wrap theme={null} buildscript { repositories { mavenCentral() } } allprojects { repositories { mavenCentral() } } ``` ## Enable Java 8 The SDK is target and source compatible with version 8 of the Java Programming Language. Enable Java 8 in the application `build.gradle(.kts)` if not done already. ```Groovy build.gradle wrap theme={null} android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } } ``` ```Kotlin build.gradle.kts theme={null} android { ... compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } ``` For more information about samples, refer to the [Android Sample](https://github.com/moengage/Android-Sample). # Data Center Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/basic-integration/data-center Configure data center redirection in the MoEngage Android SDK to comply with your data policies. # Data Redirection If your app needs to redirect data to a specific zone due to a data regulation policy, please configure the zone in the MoEngage initializer object. Use the [*setDataCenter()*](https://moengage.github.io/android-api-reference/core/com.moengage.core/-mo-engage/-builder/set-data-center.html) in the [*MoEngage.Builder*](https://moengage.github.io/android-api-reference/core/com.moengage.core/-mo-engage/-builder/index.html) to specify the data center. ```kotlin Kotlin wrap theme={null} // this is the instance of the application class and "XXXXXXXXXXX" is the APP ID from the dashboard. val moEngage = MoEngage.Builder(this, "XXXXXXXXXXX") .setDataCenter([YOUR_DATA_CENTER]) .build() MoEngage.initialiseDefaultInstance(moEngage) ``` ```java Java theme={null} // this is the instance of the application class and "XXXXXXXXXXX" is the APP ID from the dashboard. MoEngage moEngage = new MoEngage.Builder(this, "XXXXXXXXXXX") .setDataCenter([YOUR_DATA_CENTER]) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` The following details the different data centers and dashboard hosts | Data Center | Dashboard host | | --------------- | ------------------------- | | DATA\_CENTER\_1 | dashboard-01.moengage.com | | DATA\_CENTER\_2 | dashboard-02.moengage.com | | DATA\_CENTER\_3 | dashboard-03.moengage.com | | DATA\_CENTER\_4 | dashboard-04.moengage.com | | DATA\_CENTER\_5 | dashboard-05.moengage.com | **Important** The dashboard host URL provides the Data Center information of your account. Ensure that you contact your account manager or [raise a support ticket](https://help.moengage.com/hc/en-us/articles/19708702327572-Raise-a-Support-Ticket-Through-MoEngage-Dashboard) to know the data center before you change the data center in the Android SDK. # Exclude MoEngage Storage File from Auto-Backup Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/basic-integration/exclude-mo-engage-storage-file-from-auto-backup Exclude MoEngage storage files from Android auto-backup to prevent data corruption after restore. Mandatory integration step to prevent data corruption. Auto backup service of Android periodically backs up the Shared Preference file, Database files, and so on. For more information, refer to [Auto Backup](https://developer.android.com/guide/topics/data/autobackup). The backup results in MoEngage SDK identifiers to be backed up and restored after re-install. The restoration of the identifier results in your data being corrupted and the user not being reachable using push notifications. To ensure data is not corrupted after a backup is restored, opt-out of MoEngage SDK storage files. # Add a backup descriptor in the *application* tag of the Manifest file. The backup descriptor should be assigned to *fullBackupContent* attribute of the *application* tag. ```xml AndroidManifest.xml wrap theme={null} ``` # Exclude MoEngage Files in the descriptor file. Exclude the following database file and shared preference file in the descriptor to ensure these files are ***not*** backed up. ```xml XML wrap theme={null} ``` If you only want to exclude files only from MoEngage SDK instead of creating a new file you can directly add the backup descriptor file provided by the SDK to the manifest file as shown below. ```xml AndroidManifest.xml wrap theme={null} ``` For applications with **targetSdkVersion** 31 or above exclusion has to be done in the new format as well. # Exclusion for API level 31 or above ## Add manifest flag Declare the new configuration file in the manifest file as shown below. ```xml XML wrap theme={null} ``` # Exclude MoEngage Files in the configuration file. You can exclude MoEngage files from the configuration as shown below ```xml XML wrap theme={null} ... ... ... ``` If you only want to exclude files only from MoEngage SDK, instead of creating a new file, you can directly add the backup descriptor file and data extraction rules file provided by the SDK to the manifest file, as shown below. ```xml AndroidManifest.xml wrap theme={null} ``` # SDK Initialization Source: https://moengage.com/docs/developer-guide/android-sdk/sdk-integration/basic-integration/sdk-initialization Initialize the MoEngage Android SDK in your Application class using your Workspace ID and data center. # SDK Configuration Get the Workspace ID from the Settings Page of the dashboard **Dashboard** --> **Settings** --> **App** --> **General** on the MoEngage dashboard and initialize the MoEngage SDK in the Application class `onCreate()`. **Note** Initialize the SDK on the main thread inside `onCreate()` and not create a worker thread and initialize the SDK on that thread. ```kotlin Kotlin wrap theme={null} import com.moengage.core.DataCenter import com.moengage.core.MoEngage val moEngage = MoEngage.Builder(this, "YOUR_Workspace_ID", DataCenter.DATA_CENTER_X) .build() //replace X with your data center number MoEngage.initialiseDefaultInstance(moEngage) ``` ```java Java theme={null} import com.moengage.core.DataCenter; import com.moengage.core.MoEngage; MoEngage moEngage = new MoEngage.Builder(this, "YOUR_Workspace_ID", DataCenter.DATA_CENTER_X) .build(); MoEngage.initialiseDefaultInstance(moEngage); ``` In your MoEngage account, if your [portfolio](https://help.moengage.com/hc/en-us/articles/40394603054100-Portfolio) is configured with multiple projects, use the methods as shown below. ```kotlin Kotlin wrap theme={null} val moEngageBuilder = MoEngage.Builder(this, "YOUR_MOENGAGE_APP_ID", DataCenter.DATA_CENTER_1) .configureProject(ProjectConfig("")) //replace with your ProjectID ``` ```java Java theme={null} MoEngage.Builder moEngageBuilder = new MoEngage.Builder(this, "YOUR_MOENGAGE_APP_ID", DataCenter.DATA_CENTER_1) .configureProject(new ProjectConfig("")); //replace with your ProjectID ``` Following details of the different data centers you need to set based on the dashboard hosts: | Data Center | Dashboard host | | :------------------------- | :------------------------ | | `DataCenter.DATA_CENTER_1` | dashboard-01.moengage.com | | `DataCenter.DATA_CENTER_2` | dashboard-02.moengage.com | | `DataCenter.DATA_CENTER_3` | dashboard-03.moengage.com | | `DataCenter.DATA_CENTER_4` | dashboard-04.moengage.com | | `DataCenter.DATA_CENTER_5` | dashboard-05.moengage.com | | `DataCenter.DATA_CENTER_6` | dashboard-06.moengage.com | For more information about the detailed list of possible configurations, refer to the [API reference](https://moengage.github.io/android-api-reference/core/com.moengage.core/\[android-jvm]-mo-engage/-builder/index.html). **Critical** All the configurations are added to the builder before initialization. If you are calling initialize at multiple places, ensure that all the required flags and configurations are set each time you initialize to maintain consistency in behavior. # Data Flow SDK detects the build type of the installed application and the basis that it decides whether data should be sent to the Test/Live Environment of the MoEngage Platform. * UnSigned/Debug Build — Data flows to Test environment * Signed/Live Build — Data flows to Live environment. # How to fix Token Drop? Source: https://moengage.com/docs/developer-guide/android-sdk/troubleshooting-and-faqs/how-to-fix-token-drop Learn why push token drops occur in your Android app and how to fix them for reliable delivery. # What is a token drop? Token drop is a situation or case where the MoEngage Platform does not have push tokens for all the users of your application.\ Say your application is installed by 100 new users every day but there are tokens for only 60 users on the MoEngage Platform, this is regarded as a token drop. # Why is it important to fix it? To send out a push notification to your end-users push token is required, without a token push cannot be sent. Hence to keep your users engaged it is very important to fix the token drop. # Why does token drop occur? Token drop can happen because of various reasons: * Poor/No Internet connectivity which results in Firebase SDK not generating the token. * Play services version mismatch, play services version on the device isn't compatible with the Firebase version used in the application * Application has some internal check/flag based on which they decide whether to pass the token to the MoEngage SDK and during the token generation that flag is disabled hence token isn't passed to MoEngage SDK. * Integration Error, push token is not being passed to the MoEngage SDK. # How to fix it? * If the token is not available on App-Open, deploy a retry mechanism where the application periodically attempts to generate a token till a token is successfully generated. * If you have any check before passing the token to MoEngage SDK please remove it or keep the flag enabled by default to ensure tokens are passed on the first app open itself. * Revisit the [Push Notification](/developer-guide/android-sdk/push/basic/push-configuration) to check if the implementation for the passing token is properly done. # Suggestions for retry Mechanism We recommend the application attempts to generate a push token on every App-Open and pass it to the MoEngage SDK. In case the app does not get the token from the Firebase API for any reason, the should attempt to register for push again periodically till the registration is successful or till the application is foreground.\ You can refer to this [library](https://github.com/umang91/fcm-client-lib) as an example of how to set up a retry mechanism. Alternatively, you can use this library instead of setting the mechanism yourself. * This is not an official library from MoEngage; this library is built by one of the developers at MoEngage. * MoEngage SDK already has a retry mechanism built to reduce token drop. We recommend you use MoEngage SDK's token registration to ensure no or minimal token drop(less than 2%). Refer to the [Push Notification](/developer-guide/android-sdk/push/basic/push-configuration) documentation to learn more about how you let MoEngage SDK handle your Push token. # How to share Android MoEngage SDK logs Source: https://moengage.com/docs/developer-guide/android-sdk/troubleshooting-and-faqs/how-to-share-android-moengage-sdk-logs Enable and share verbose MoEngage Android SDK logs with the support team to resolve issues faster. Sometimes, our support team will ask for logs as the first step to resolve the issue faster. Logs can help us and in some cases you quickly identify the issue and share the exact solution to a problem.  In this document, we list a few steps that you can execute to share the MoEngage SDK logs with the MoEngage support team.