openapi: 3.0.3
info:
title: MoEngage Email Subscription Management APIs
description: |
APIs for managing user email resubscription and opt-in status.
This suite of APIs allows you to update the email subscription and opt-in preferences for your users directly within the MoEngage platform, and optionally synchronize resubscription status with an external Email Service Provider (ESP).
version: '1.0'
servers:
- url: https://api-{dc}.moengage.com
description: MoEngage API Server
variables:
dc:
default: '01'
description: 'The ‘dc’ in the API Endpoint URL refers to the MoEngage Data Center (DC). MoEngage hosts each customer in a different DC. You can find your DC number and replace the value of ‘dc’ in the URL by referring to the DC and API endpoint mapping [here](/api/introduction#data-centers). Your MoEngage Data Center (DC) can be 01, 02, 03, 04, 05, 06, or 101.'
tags:
- name: Resubscribe
description: Resubscribe users who previously unsubscribed, and optionally update the ESP suppression list.
- name: Opt-in Management
description: Update user email opt-in status and category preferences in MoEngage.
security:
- basicAuth: []
paths:
/emails/v1.0/bulk-resubscribe:
post:
tags:
- Resubscribe
summary: Bulk Resubscribe Users
description: |
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.
operationId: bulkResubscribeUsers
x-mint:
content: |
#### 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.
parameters:
- name: MOE-APPKEY
in: header
required: true
schema:
type: string
description: |
This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**.
example: 'YOUR_WORKSPACE_ID_XXXX'
requestBody:
description: List of recipients to resubscribe and ESP preference.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeRequest'
example:
recipients:
- jane@domain.com
- mike@example.com
- john.doe@example.com
update_esp: true
esp: SENDGRID
request_id: '636b77e6e2cf83277195fb60'
responses:
'202':
description: The request has been successfully submitted for asynchronous processing.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeSuccessResponse'
example:
message: The request is submitted successfully.
response_id: SrTuWVlPsq
'400':
description: Bad Request. Returned for issues like missing mandatory fields (e.g., `recipients`), invalid format, too many recipients (>100), or invalid ESP settings.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError400Response'
examples:
missingRecipients:
summary: Missing recipients field
value:
response_id: wkskLzEMwM
error:
message: Request_Body is mandatory. Kindly add request_body and the desired fields in the API payload.
err_code: BadRequest
missingRequestId:
summary: Missing request_id field
value:
response_id: jLcIFgNqiF
error:
message: request_id - Field is required but value is None
err_code: InvalidFieldValue
tooManyRecipients:
summary: Too many recipients (>100)
value:
response_id: ofVaFGNZeU
error:
message: Payload limit is set to 100
err_code: BadRequest
invalidRecipientFormat:
summary: Invalid email format in recipients
value:
response_id: CNjLIXzCxP
error:
message: Please provide input in a valid email address format (example@domain.com) as part of 'Recipients'.
err_code: InvalidInput
emptyRecipients:
summary: Empty recipients array
value:
response_id: VkJTiAOgxt
error:
message: Add at least one email address as part of the 'Recipients'
err_code: InvalidInput
invalidEspSettings:
summary: Invalid Email Connector Settings
description: Occurs if the configured ESP settings are incorrect or the ESP is not SendGrid when `update_esp` is true.
value:
response_id: GENERATED_ID
error:
message: Valid email settings not present
err_code: InvalidSettings # FIXME: Confirm actual error code
'401':
description: Authorization Failure. Returned for issues like `MOE-APPKEY` header mismatch with Basic Auth username, missing Basic Auth credentials, or invalid authentication type.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError401Response'
examples:
headerMismatch:
summary: MOE-APPKEY mismatch
value:
response_id: YNJhkZzfqt
error:
message: MOE_APPKEY doesn't match the Username (APP_KEY) used in Basic Auth authorization.
err_code: HeaderMismatch
missingPassword:
summary: Missing password in Basic Auth
value:
response_id: dKzDpSIiCG
error:
message: Password (APP_SECRET) is missing in the Basic Auth authorization.
err_code: AuthenticationMissing
'405':
description: Method Not Allowed. Returned when a method other than POST is used (e.g., GET).
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError405Response'
example:
response_id: GudkCOBkHT
error:
message: This API only supports the POST method. Kindly update the method and retry again.
err_code: MethodNotAllowed
'415':
description: Unsupported Media Type. Returned when the `Content-Type` header is missing or invalid.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError415Response'
example:
response_id: quUXnIinLK
error:
message: The header 'Content-Type' is missing. Kindly provide the header 'Content-Type' and set it as 'application/json'
err_code: HeaderMissing
'429':
description: Rate Limit Breach. The request rate has exceeded the limit of 10 RPM.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError429Response'
example:
response_id: quUXnIinLK
error:
message: Rate limit exceeded
err_code: TooManyRequests
'500':
description: Internal Server Error.
content:
application/json:
schema:
$ref: '#/components/schemas/ResubscribeError500Response'
example:
response_id: quUXnIinLK
error:
message: Please Contact Moengage Team
err_code: INTERNAL_SERVER_ERROR
/v1.0/opt-in-management/user-preferences:
put:
tags:
- Opt-in Management
summary: Update User Email Opt-in Preferences
description: |
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).
operationId: updateEmailOptinPreferences
x-mint:
content: |
#### 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.
parameters:
- name: MOE-APPKEY
in: header
required: true
schema:
type: string
description: |
This is the Workspace ID of your MoEngage account that must be passed with the request. You can find it in the MoEngage dashboard at **Settings** > **Account** > **APIs** > **Workspace ID (earlier app id)**.
example: 'YOUR_WORKSPACE_ID_XXXX'
requestBody:
description: The request body contains the user's email preference details encapsulated in a `user_preferences` object.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OptinRequest'
example:
user_preferences:
customer_id: ID_uid
email_id: john@example.com
categories:
category_1: true
category_2: false
opt_in_status: DOUBLE_OPTED_IN
channel: email
responses:
'200':
description: The request has been processed successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/OptinSuccessResponse'
example:
message: Your request has been processed successfully
'400':
description: Bad Request. Returned when required parameters are missing, incorrect data types are used, invalid values are passed (e.g., invalid `opt_in_status`), or the user is not found.
content:
application/json:
schema:
$ref: '#/components/schemas/OptinError400Response'
examples:
invalidDataType:
summary: Invalid Data Type
value:
error:
code: 400 Bad Request
message: Request Data is invalid.
details:
target: customer_id
message: "Wrong data type was used for - Value must be of type (,), passed type: : False."
invalidOptInStatus:
summary: Invalid Opt-in Status Value
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: opt_in_status
message: "Opt-In status can only be 'DOUBLE_OPTED_IN' or 'OPTED_OUT' or 'OPT_IN_PENDING' (case-insensitive). Please provide the correct value."
missingIdOrEmail:
summary: Missing customer_id or email_id
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: customer_id or email_id
message: Either customer_id or email_id is mandatory. Please provide at least one of them.
userNotFound:
summary: User Not Found
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: customer_id or email_id
message: No users found with the provided customer_id or email_id. Please check the same.
invalidCategory:
summary: Invalid or Inactive Category
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: categories
message: Categories A, B, C are either invalid or not active in the Workspace. Please check the categories in the request.
extraKey:
summary: Extra Key Passed in Request
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: "['customerid']"
message: Extra key passed in the request
invalidChannel:
summary: Invalid Channel Value
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: channel
message: "Channel can only be ['email'] (case-insensitive). Please provide the correct channel."
customerIdMandatory:
summary: customer_id Mandatory (Unsubscribe On Email Disabled)
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: customer_id
message: customer_id is mandatory when unsubscribe on email is not enabled.
noActiveCategories:
summary: No Active Categories in Workspace
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: categories
message: There are no active categories found. Please remove the categories from the request data or setup the subscription categories in MoEngage Email settings.
allCategoriesInvalid:
summary: All Provided Categories Invalid or Inactive
value:
error:
code: 400 Bad Request
message: Request Data is invalid
details:
target: categories
message: All provided categories are either invalid or not active in the Workspace. Please check the categories in the request.
sentryCheckFailed:
summary: Sentry Check Failed
value:
message: Sentry check failed
'401':
description: Unauthorized. Authentication failed (e.g., missing Authorization header, wrong Workspace ID, or wrong Data API Key).
content:
application/json:
schema:
$ref: '#/components/schemas/OptinError401Response'
examples:
missingAuthHeader:
summary: Missing Authorization Header
value:
error:
code: 401 Unauthorized
message: Authentication failed.
details:
target: Authorization Header
message: Authorization header is missing
wrongDataKey:
summary: Wrong Data API Key
value:
error:
code: 401 Unauthorized
message: Authentication failed
details:
target: Data key
message: Data API key is wrong. Please provide correct Data API Key as password.
'403':
description: Forbidden. Returned when the Email Opt-in Management feature is not enabled for the workspace.
content:
application/json:
schema:
$ref: '#/components/schemas/OptinError403Response'
example:
error:
code: 403 Forbidden
message: Feature not enabled
details:
target: Email Opt-in Management
message: Email Opt-in Management feature not enabled for the workspace. Please reach out to MoEngage to get it enabled.
'429':
description: Too Many Requests. The request rate has exceeded the limit of 1000 RPM or 360K per day.
content:
application/json:
schema:
$ref: '#/components/schemas/OptinError429Response'
'500':
description: Internal Server Error.
content:
application/json:
schema:
$ref: '#/components/schemas/OptinError500Response'
example:
error:
code: 500 Internal Server Error
message: Something went wrong, Please contact MoEngage Team.
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 **Data** tile.
For more information on authentication and getting your credentials, refer [here](https://www.moengage.com/docs/api/introduction#getting-your-credentials).
schemas:
# Resubscribe Schemas
ResubscribeRequest:
type: object
required:
- recipients
- esp
- request_id
properties:
recipients:
type: string
description: 'This field contains the email ids of the users who have resubscribed.
**Note:** If an email address matches multiple profiles, all the profiles will be marked as resubscribed on the MoEngage dashboard (the unsubscribe flag will be set to false for the user).'
example: ["john@example.com", "mike@example.com"]
customer_id:
type: string
description: 'This field denotes the unique identifier used to identify a user in MoEngage. Note that devices can be created for existing users only.'
esp:
type: string
description: 'This field contains information about the Email Service Provider (esp) whose suppression list needs to be updated. For example, “esp”: “SENDGRID” would imply that the email address of the customers who have resubscribed to your brand need to be removed from SendGrid’s suppression list.'
update_esp:
type: boolean
description: 'This field’s default value is false when it is not sent in the request payload. MoEngage calls the ESP to remove the email addresses from their email suppression list when this field is true.'
request_id:
type: string
description: 'This field contains the value of the identifier for the request.'
ResubscribeSuccessResponse:
type: object
description: Success response body for the Bulk Resubscribe API (202 Accepted).
properties:
message:
type: string
description: This field contains a brief description of the request status.
example: The request is submitted successfully.
response_id:
type: string
description: This field contains the unique identifier for the response and is present in the response only when the request is successful.
example: SrTuWVlPsq
ResubscribeError400Response:
type: object
description: This response is returned when the `recipients` field is not present in the request body (400 Bad Request).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
ResubscribeError401Response:
type: object
description: This response is returned when the authorization fails due to invalid credentials or setup (401 Authorization Failure).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
ResubscribeError405Response:
type: object
description: This response is returned when the wrong HTTP method is used for the API (405 Method Not Allowed).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
ResubscribeError415Response:
type: object
description: This response is returned when the Content-Type header is missing or unsupported (415 Unsupported Media Type).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
ResubscribeError429Response:
type: object
description: This response is returned when the number of requests has exceeded the rate limit (429 Rate Limit Breach).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
ResubscribeError500Response:
type: object
description: This response is returned when the system runs into an unexpected error (500 Internal Server Error).
properties:
response_id:
type: string
description: Unique identifier for the response.
error:
type: object
description: Contains the error details.
properties:
message:
type: string
description: A brief description of the error.
err_code:
type: string
description: The error code for the unsuccessful request.
# Opt-in Management Schemas
OptinRequest:
type: object
description: The main wrapper object for the user preferences payload.
required:
- user_preferences
properties:
user_preferences:
$ref: '#/components/schemas/UserPreferences'
UserPreferences:
type: object
description: |
Contains the user's opt-in preferences. Must contain either `customer_id` or `email_id`.
required:
- opt_in_status
- channel
properties:
customer_id:
type: string
description: |
Unique identifier for the user in MoEngage. Optional, if `email_id` is passed.
To avoid error, make sure you pass either `customer_id` or `email_id`.
If you are passing `customer_id`, `email_id` is not mandatory.
If you pass only `customer_id`, MoEngage finds the user with this `customer_id` and updates the opt-in status accordingly.
Generally, when `email_id` is passed, MoEngage finds all users with this `email_id` and updates the opt-in status accordingly. But if you don't want all the users with this `email_id` to be updated, you can contact the MoEngage team.
`customer_id` is mandatory if you don't want to pass the opt-in status update to all users with the same email ID.
example: ID_uid
email_id:
type: string
format: email
description: |
Email ID of the user. Optional if `customer_id` is provided.
If only `email_id` is provided, all users with this email may be updated (contact MoEngage support to configure behavior).
To avoid error, make sure you pass `customer_id` or `email_id`.
If you are passing `email_id`, `customer_id` is not mandatory.
If you pass only `email_id`, MoEngage finds all the users with this `email_id` and updates the opt-in status accordingly.
You can also pass both `customer_id` and `email_id`. In this case, `email_id` is given the highest priority, and MoEngage finds all users with this `email_id` and updates the opt-in status accordingly.
You can contact the MoEngage team if you don't want to update the opt-in status of all users with the same email ID.
example: john@example.com
categories:
type: object
description: |
Subscription status for defined categories in your dashboard.
Keys are category names, values are boolean (`true`=subscribed). If even one category is invalid/inactive, the entire request will fail.
**Note**: If this is passed and all category values are `false`, the overall `opt_in_status` will be overridden to **OPTED_OUT** even if `DOUBLE_OPTED_IN` is passed.
additionalProperties:
type: boolean
example:
category_1: true
category_2: false
opt_in_status:
type: string
description: |
The user's overall email opt-in status.
Note:
This field is case-insensitive, but ensure that you follow the same format as in the example.
You can pass both `categories` and `opt_in_status`. In this case, if all category values are `false` and `opt_in_status` is `DOUBLE_OPTED_IN`, MoEngage gives high priority to category-level information and the opt-in status is updated as `OPTED_OUT`.
enum: [DOUBLE_OPTED_IN, OPTED_OUT, OPT_IN_PENDING]
example: DOUBLE_OPTED_IN
channel:
type: string
description: The channel for which the opt-in status applies. Currently, only **email** is supported.
enum: [email]
example: email
OptinSuccessResponse:
type: object
description: Success response body for the Opt-in Management API (200 OK).
properties:
message:
type: string
description: The success message denoting the request was processed successfully.
example: Your request has been processed successfully
OptinError400Response:
type: object
description: This response is returned when the required parameters are missing from the request, attributes are not found, or incorrect values are passed.
properties:
error:
type: object
properties:
code:
type: string
description: The HTTP status code and text (e.g., '400 Bad Request').
example: 400 Bad Request
message:
type: string
description: A brief message denoting the type of error.
example: Request Data is invalid.
details:
type: object
description: Contains granular error information including the target field and a detailed error message.
properties:
target:
type: string
description: The field where the error occurred (e.g., `customer_id`).
example: customer_id
message:
type: string
description: The details of the error message.
example: "Wrong data type was used for ..."
OptinError401Response:
type: object
description: This response is returned when the request does not have valid authentication credentials.
properties:
error:
type: object
properties:
code:
type: string
description: The HTTP status code and text (e.g., '401 Unauthorized').
example: 401 Unauthorized
message:
type: string
description: A brief message denoting the type of error.
example: Invalid API Key provided.
details:
type: object
description: Contains granular error information including the target field and a detailed error message.
properties:
target:
type: string
description: The authentication scheme or header.
example: Authorization Header
message:
type: string
description: The details of the error message.
example: "Authentication failed due to missing or invalid credentials."
OptinError403Response:
type: object
description: This response is returned when the Email Opt-in Management feature is not enabled for the workspace.
properties:
error:
type: object
properties:
code:
type: string
description: The HTTP status code and text (e.g., '403 Forbidden').
example: 403 Forbidden
message:
type: string
description: A brief message denoting the type of error.
example: Feature not enabled for workspace.
details:
type: object
description: Contains granular error information including the target field and a detailed error message.
properties:
target:
type: string
description: The resource or feature that is forbidden.
example: Email Opt-in Management
message:
type: string
description: The details of the error message.
example: "Access to the Email Opt-in Management API is forbidden. Please enable the feature in your workspace settings."
OptinError429Response:
description: There is no response body for this error.
OptinError500Response:
type: object
description: Error response body for Internal Server Error (500).
properties:
error:
type: object
properties:
code:
type: string
example: 500 Internal Server Error
message:
type: string
example: Something went wrong, Please contact MoEngage Team.