openapi: 3.0.3 info: title: MoEngage Catalog API description: | This API allows for the management of product and item catalogs, including **creation**, **attribute definition**, **item ingestion, updates, deletion**, and **retrieval**. Authentication is handled via **Basic Auth** (using your Workspace ID as username and API Key as password), and all requests additionally require the `MOE-APPKEY` header (Workspace ID). The API has a platform-wide rate limit of **100 requests/minute OR 1000 requests/hour**, with a maximum payload size of **5MB**. x-mint: content: | #example 500 max # version: '1.0' servers: - url: 'https://api-{dc}.moengage.com/v1' variables: dc: default: '01' description: "The ‘dc’ in the API Endpoint URL refers to the MoEngage Data Center (DC). MoEngage hosts each customer in a different DC. You can find your DC number and replace the value of ‘dc’ in the URL by referring to the DC and API endpoint mapping [here](/api/introduction#data-centers). Your MoEngage Data Center (DC) can be 01, 02, 03, 04, 05, 06, or 101." tags: - name: Catalog description: Operations related to creating and managing catalog schemas (attributes). - name: Items description: Operations related to ingesting, updating, and deleting items within a catalog. security: - basicAuth: [] # Basic Auth for API Key/Secret paths: /catalog: post: tags: - Catalog summary: Create Catalog operationId: createCatalog description: | This API creates a new catalog with a unique name. You can specify the necessary attributes along with their respective data types. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCatalogRequest' examples: example-1: summary: Basic catalog creation value: name: "SummerCollection2024" price_currency: "USD" attributes: - name: "id" type: "string" - name: "title" type: "string" - name: "link" type: "string" - name: "image_link" type: "string" - name: "price" type: "double" - name: "in_stock" type: "bool" - name: "sale_start_date" type: "datetime" - name: "store_location" type: "geopoint" responses: '201': description: Catalog created successfully. content: application/json: schema: type: object properties: catalog_id: type: string description: | The unique ID corresponding to a successful catalog creation, returned as a 24-character hex string. Store this ID and use it as a path parameter for all subsequent item ingestion and modification requests. example: "507f1f77bcf86cd799439011" example: catalog_id: "507f1f77bcf86cd799439011" '400': description: Bad Request - Validation or logic error. content: application/json: schema: $ref: '#/components/schemas/Error' examples: duplicate-name: summary: Duplicate Catalog Name value: error-code: "duplicate-catalog-name" message: "Catalog name already exists. Please use a different name for your catalog and try again." invalid-datatype: summary: Invalid Data Type value: error-code: "invalid-request" message: > The data type provided for some of the attributes is invalid. Provided value: You can add attributes with valid data types - [bool, double, string, datetime, geopoint] only missing-attributes: summary: Missing Mandatory Attributes value: error-code: "missing-mandatory-attributes" message: "You must include mandatory attributes: id, title, link, and image_link with string data type and try again. Invalid or absent attributes: " catalog-limit-exceeded: summary: Catalog Limit Exceeded value: error-code: "catalog-limit-exceeded" message: "You have exceeded the total limit of 35 catalogs for your account. You need to delete unused catalogs from the dashboard and try again." attribute-limit-exceeded: summary: Attribute Limit Exceeded value: error-code: "attribute-limit-exceeded" message: "Your catalog has exceeded the maximum limit of 50 attributes per catalog. Please reduce the number of attributes and try again." '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' # Reference added as requested '409': description: Conflict - A catalog with the provided name already exists. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "duplicate-catalog-name" message: "Catalog name already exists. Please use a different name for your catalog and try again." '413': description: Payload Too Large - Attribute limit exceeded. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "too-many-attributes" message: "Maximum allowed attributes is 50" '429': $ref: '#/components/responses/TooManyRequests' /catalog/{catalog_id}/attributes: patch: tags: - Catalog summary: Add Catalog Attributes operationId: addCatalogAttributes description: | This API adds new attributes to the catalog. If the API request contains attributes that already exist, they will not be added again. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string - $ref: '#/components/parameters/CatalogIdPath' requestBody: required: true content: application/json: schema: type: object required: - attributes properties: attributes: type: array description: A list of new attributes to add to the catalog schema. items: $ref: '#/components/schemas/AttributeDefinition' examples: example-1: summary: Add new attributes value: attributes: - name: "color" type: "string" - name: "weight_kg" type: "double" - name: "sale_start_date" type: "datetime" - name: "store_location" type: "geopoint" responses: '202': description: Accepted. The request was processed. The response contains a list of attributes that were already present and ignored. content: application/json: schema: type: object properties: success: type: boolean example: true duplicate-item-attributes: type: array description: A list of attributes that already existed in the catalog and were ignored. items: type: string example: ["pricing"] examples: new-attribute-added: summary: New attribute added successfully description: All requested attributes were new and added to the catalog. The `duplicate-item-attributes` array is empty. value: success: true duplicate-item-attributes: [] duplicate-attribute: summary: Duplicate attribute ignored description: One or more requested attributes already existed on the catalog and were ignored. The duplicates are listed in `duplicate-item-attributes`. value: success: true duplicate-item-attributes: - pricing '400': description: Bad Request - Attribute already exists. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "attribute-exists" message: "Attribute already exists in the catalog" '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '413': description: Payload Too Large - Maximum attributes exceeded. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "too-many-attributes" message: "Maximum allowed attributes is 50" '429': $ref: '#/components/responses/TooManyRequests' /catalog/{catalog_id}/items: post: tags: - Items summary: Add Items operationId: ingestCatalogItems description: | This API ingests items into an existing catalog as long as the attributes provided during ingestion match the attributes provided during catalog creation. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string - $ref: '#/components/parameters/CatalogIdPath' requestBody: required: true content: application/json: schema: type: object required: - items properties: items: type: array maxItems: 50 description: An array of item objects to add to the catalog. Each item must contain the mandatory attributes (`id`, `title`, `link`, `image_link`), and may include any custom attributes you have defined on the catalog. Custom attributes must already exist on the catalog (added at creation or via Add Catalog Attributes). items: $ref: '#/components/schemas/CatalogItem' responses: '200': description: OK. The ingestion request was processed. The response body contains details on valid and invalid item counts. content: application/json: schema: $ref: '#/components/schemas/IngestUpdateResponse' example: message: valid: count: 1 invalid: count: 8 details: - error-id: duplicate-item-ids message: "Item ids within a catalog must be unique. Please ensure your request contains unique item ids for the given catalog and try again." count: 1 document_ids: - '567890' - error-id: missing-mandatory-attributes message: "Your must include mandatory attributes: id, title, link, and image_link with string data type and try again." count: 1 document_ids: - '567890' - error-id: invalid-datatype-attribute message: "The provided item attribute {attribute name} with value {attribute value} can't be converted to the data type {data type} as defined in the catalog schema." count: 1 document_ids: - '7523675' - error-id: invalid-item-attribute message: "The provided item attribute is not part of the defined catalog schema. Please check your catalog schema and try again. Undefined attributes: shipping_price" count: 2 document_ids: - '312' - '8291379' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '413': $ref: '#/components/responses/PayloadTooLarge' '429': $ref: '#/components/responses/TooManyRequests' patch: tags: - Items summary: Update Items operationId: updateCatalogItems description: | This API updates items with new attribute values. Attributes must adhere to the data type defined. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string - $ref: '#/components/parameters/CatalogIdPath' requestBody: required: true content: application/json: schema: type: object required: - items properties: items: type: array maxItems: 50 description: An array of item updates. Each object must contain the item `id` and the `attributes` to update. items: $ref: '#/components/schemas/ItemUpdate' example: items: - id: Existing_item_ID attributes: attribute_name: updated_value - id: test2 attributes: price: 98 sale_start_date: "2025-08-27T19:26:38.00Z" store_location: "12.9716,77.5946" responses: '200': description: OK. The update request was processed. The response body contains details on valid and invalid item counts. content: application/json: schema: $ref: '#/components/schemas/IngestUpdateResponse' example: message: valid: count: 1 invalid: count: 8 details: - error-id: item-not-found message: "Item with id %s not found in the catalog. Please check the item id and try again." count: 1 document_ids: - '567890' - error-id: invalid-attributes message: "Some of the attributes are not defined in the catalog schema: (shipping_city)" count: 2 document_ids: - '312' - '8291379' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '413': $ref: '#/components/responses/PayloadTooLarge' '429': $ref: '#/components/responses/TooManyRequests' /catalog/{catalog_id}/items/bulk-delete: post: tags: - Items summary: Delete Items operationId: deleteCatalogItems description: | This API deletes existing items in a given catalog. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string - $ref: '#/components/parameters/CatalogIdPath' requestBody: required: true content: application/json: schema: type: object required: - items properties: items: type: array maxItems: 50 description: An array of item IDs to delete from the catalog. items: type: string example: "item_id_123" example: items: - "{{item_ID}}" responses: '202': description: Accepted. The bulk delete request was processed successfully. content: application/json: schema: type: object properties: message: type: object properties: valid: type: object properties: count: type: integer description: The number of items successfully deleted. invalid: type: object properties: count: type: integer description: The number of items that were not found and could not be deleted. example: message: valid: count: 0 invalid: count: 10 '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '413': $ref: '#/components/responses/PayloadTooLarge' '429': $ref: '#/components/responses/TooManyRequests' /catalog/{catalog_id}/items/search: post: tags: - Items summary: Get Items operationId: getItemDetails description: | 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. x-mint: content: | #### 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. parameters: - name: MOE-APPKEY in: header description: "This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**." required: true schema: type: string - $ref: '#/components/parameters/CatalogIdPath' requestBody: required: true content: application/json: schema: type: object required: - items properties: items: type: array maxItems: 50 description: | A list of unique IDs (strings) that represent the items you want to fetch. This field accepts a maximum of **50 item IDs** per request. If the count exceeds this limit, the request results in an error. **Note**: The request may fail if mandatory attributes are missing from the item configuration. items: type: string example: - "P001" - "P002" - "P003" - "P004" example: items: - "P001" - "P002" - "P003" - "P004" responses: '200': description: Items retrieved successfully. content: application/json: schema: $ref: '#/components/schemas/GetItemDetailsResponse' example: items: - catalog_id: "{{catalog_id}}" feed_id: "{{feed_id}}" title: "string" description: "string" link: "https://link.in/" image_link: "https://link.in/" price_currency: "USD" creation_date: "2024-05-10T07:03:00.18Z" last_updated: "2024-05-10T07:03:00.18Z" product_id: "string" price: 29.99 date: "2022-04-05T00:00:00.00Z" sale_start_date: "2025-08-27T19:26:38.00Z" store_location: "12.9716,77.5946" '400': description: Bad Request - Invalid request format or item count validation failed. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "invalid-request" message: "Item count should be greater than 0 and less than or equal to 50" '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '413': $ref: '#/components/responses/PayloadTooLarge' '429': $ref: '#/components/responses/TooManyRequests' components: securitySchemes: basicAuth: type: http scheme: basic description: | Authentication is done via Basic Auth. This requires a base64-encoded string of your credentials in the format 'username:password'. - **Username**: Use your MoEngage workspace ID (also known as the App ID). You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**. - **Password**: Use your API Key, which you can find within the **Campaign report/Business events/Custom templates/Catalog API/Inform Report** tile. For more information on authentication and getting your credentials, refer [here](https://www.moengage.com/docs/api/introduction#getting-your-credentials). AppKeyHeader: type: apiKey in: header name: MOE-APPKEY description: | This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**. parameters: CatalogIdPath: name: catalog_id in: path required: true description: The unique identifier for the catalog, obtained during catalog creation. schema: type: string schemas: AttributeDefinition: type: object required: - name - type properties: name: type: string description: The name of the attribute (e.g., 'color', 'price'). type: type: string description: | The data type of the attribute. Supported values: - `string` — text values. - `bool` — boolean values (`true` or `false`). - `double` — numeric values, including decimals. - `datetime` — ISO 8601 timestamp with milliseconds and a UTC offset (`Z` or `±HH:mm`). Example: `2025-08-27T19:26:38.00Z`. - `geopoint` — a geographic coordinate as `"latitude,longitude"`. Example: `"12.9716,77.5946"`. enum: [string, bool, double, datetime, geopoint] CreateCatalogRequest: type: object required: - name - attributes - price_currency properties: name: type: string description: A unique name for the catalog. example: "ProductCatalog" price_currency: type: string description: The ISO 4217 currency code for prices in the catalog. enum: [USD, CAD, EUR, AED, AFN, ALL, AMD, AOA, ARS, AUD, AZN, BAM, BDT, BGN, BHD, BIF, BND, BOB, BRL, BWP, BYR, BZD, CDF, CHF, CLP, CNY, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EEK, EGP, ERN, ETB, GBP, GEL, GHS, GNF, GTQ, HKD, HNL, HRK, HUF, IDR, ILS, INR, IQD, IRR, ISK, JMD, JOD, JPY, KES, KHR, KMF, KRW, KWD, KZT, LBP, LKR, LTL, LVL, LYD, MAD, MDL, MGA, MKD, MMK, MOP, MUR, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, OMR, PAB, PEN, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SDG, SEK, SGD, SOS, SYP, THB, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, UYU, UZS, VEF, VND, XAF, XOF, YER, ZAR, ZMK] attributes: type: array maxItems: 50 description: | An array defining the schema of attributes for this catalog. **title** - name of the item (string) **link** - weblink of the item (string) **id** - unique ID of that represent this item item (string) **image_link** - image source link of this item (string) items: $ref: '#/components/schemas/AttributeDefinition' CatalogItem: type: object required: - id - title - link - image_link properties: id: type: string description: The unique identifier for the catalog item. title: type: string description: The title or name of the catalog item. link: type: string format: uri description: The deep link or URL to the item's page. image_link: type: string format: uri description: The URL of the primary image for the item. # Allows for all other user-defined attributes based on AttributeDefinition additionalProperties: true example: id: "item-sku-123" title: "Classic T-Shirt" link: "https://example.com/products/item-123" image_link: "https://example.com/images/item-123.jpg" brand_attribute: "Super Tech" in_stock: true price: 19.99 sale_start_date: "2025-08-27T19:26:38.00Z" store_location: "12.9716,77.5946" ItemUpdate: type: object required: - id - attributes properties: id: type: string description: The unique ID of the item to update. attributes: type: object description: | A key-value map of attributes to update for the item. The keys must match existing attributes in the catalog schema, and values must match the defined data types. additionalProperties: true example: price: 24.99 in_stock: false GetItemDetailsResponse: type: object properties: items: type: array description: A list of catalog item objects matching the requested item IDs. items: type: object properties: catalog_id: type: string description: The unique identifier for the catalog. feed_id: type: string description: The feed ID associated with the item. title: type: string description: The title or name of the catalog item. description: type: string description: The description of the catalog item. link: type: string format: uri description: The deep link or URL to the item's page. image_link: type: string format: uri description: The URL of the primary image for the item. price_currency: type: string description: The ISO 4217 currency code for the item price. creation_date: type: string format: date-time description: The date and time when the item was created. last_updated: type: string format: date-time description: The date and time when the item was last updated. product_id: type: string description: The product ID of the item. price: type: number format: double description: The price of the item. date: type: string format: date-time description: A date attribute associated with the item. additionalProperties: true Error: type: object properties: error-code: type: string description: A machine-readable error code. message: type: string description: A human-readable description of the error. IngestUpdateResponse: type: object properties: message: type: object properties: valid: type: object properties: count: type: integer description: The number of items successfully processed. invalid: type: object properties: count: type: integer description: The number of items that failed processing. details: type: array items: type: object properties: error-id: type: string description: A unique ID indicating the type of ingestion/update failure. example: "duplicate-item-ids" message: type: string description: The reason for the failure. example: "Item ids within a catalog must be unique." count: type: integer description: The number of items that failed due to this specific error. example: 1 document_ids: type: array items: type: string description: The IDs of the items that failed. example: ["item_id_xyz"] responses: BadRequest: description: Bad Request - The request is improperly formatted, or contains missing/invalid parameters. content: application/json: schema: $ref: '#/components/schemas/Error' examples: invalid-datatype: value: error-code: "invalid-request" message: "The data type provided for some of the attributes is invalid." invalid-json: value: error-code: "invalid-request" message: "The request body is not a valid JSON. Please provide a valid JSON request body." limit-exceeded: value: error-code: "invalid-request" message: "items size should be greater than 0 and less than or equal to 50" Unauthorized: description: Unauthorized - The request does not have valid authentication credentials. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "request-unauthenticated" message: "Your request is unauthorized. Please verify your credentials and try again." Forbidden: description: Forbidden - The client does not have access rights to the Catalog APIs. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "request-denied" message: "Your account does not have access to the Catalog APIs." NotFound: description: Not Found - The specified resource (catalog) could not be found. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "catalog-not-found" message: "We could not find any API based catalog for the provided catalog id." PayloadTooLarge: description: Payload Too Large - The request payload exceeds the 5MB limit. content: application/json: schema: $ref: '#/components/schemas/Error' example: error-code: "payload-size-exceeded" message: "Your payload size exceeds the 5MB limit. Please reduce the payload size and try again." TooManyRequests: description: | Too Many Requests - The rate limit for the API has been exceeded. The following headers are returned in case of rate-limit breach: * **x-ratelimit-limit (integer)**: The maximum number of requests that the consumer is permitted to make in a given time window. * **x-ratelimit-remaining (integer)**: The number of requests remaining in the current rate limit window. * **x-ratelimit-reset (integer)**: The time at which the current rate limit window resets in UTC epoch seconds.