> ## Documentation Index
> Fetch the complete documentation index at: https://moengage.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscription Categories (V5)

> Read and manage a user's Subscription Category preferences server-to-server, without depending on MoEngage-hosted landing-page flows.

The MoEngage Subscription Preferences API (V5) lets you read and manage a user's Subscription Category preferences directly from your own systems, without depending on MoEngage-hosted landing-page flows. Users are identified by a `user_identifier_type` / `user_identifier_value` pair (`moe_user_id`, `uid`, or `email`), rather than a path parameter.

> [!NOTE]
>
> The Subscription Preferences (V5) API supports only the email channel.
>
> * For PII-tokenized databases, only UID and MoEngage ID are supported.
> * For PII-encrypted databases, the API also accepts the encrypted email value.

## Endpoints

The Subscription Categories (V5) API consists of the following endpoints:

* [Get Subscription Categories (V5)](https://moengage.com/docs/api/subscription-categories/get-subscription-categories-v5.md): Fetches the active subscription-category catalog for the workspace.
* [Get Subscription Preferences (V5)](https://moengage.com/docs/api/subscription-preferences/get-subscription-preferences-v5.md): Fetches a user's per-category subscription state and global unsubscribe status.
* [Update Subscription Preferences (V5)](https://moengage.com/docs/api/subscription-preferences/update-subscription-preferences-v5.md): Updates a user's per-category subscription state and/or global unsubscribe status. The update is processed asynchronously — the endpoint returns `202 Accepted` and does not confirm the update has been applied.

> [!NOTE]
>
> **Transitional authentication note:** This route currently accepts HTTP Basic Auth only. Bearer token support is planned but not yet active on this path — Bearer requests return `401` until the APISIX gateway fronts this route.

## IP Whitelisting

Use the [API Firewall](https://moengage.com/docs/user-guide/settings/account/security/api-firewall.md) to restrict which IP addresses can call the APIs in the Campaigns category. After you publish a rule for this category, only your whitelisted servers can reach these APIs, even if an API key is exposed. Requests from any other IP address receive a `403` response.

## FAQs

### Get Subscription Categories

> **Do I need to pass a user identifier to this endpoint?**
>
> No. This endpoint returns the workspace's full active subscription-category catalog and isn't scoped to any individual user — you only need to authenticate the request.

> **How fresh is the category data returned by this endpoint?**
>
> The catalog is served from the existing hourly category cache, so a category you just created or edited in the dashboard may take up to an hour to appear here.

> **What happens if I don't pass the channel filter?**
>
> Categories for all channels are returned. Since this API supports only the email channel at present, passing `channel=email` returns the same catalog.

### Get Subscription Preferences

> **What if the email I pass matches more than one user profile?**
>
> When the `EMAIL_UNSUB_BASED_ON_EMAIL` sentry flag is on, MoEngage processes every user profile that has the same email address.

> **What if no profile matches the identifier I passed?**
>
> The call returns `404`.

> **Can I use moe\_user\_id, uid, or email interchangeably?**
>
> Yes — set `user_identifier_type` to whichever identifier you hold (`moe_user_id`, `uid`, or `email`) along with the matching `user_identifier_value`. You don't need to look up a different identifier first.

### Update Subscription Preferences

> **Why did I get a 202 instead of the updated preferences?**
>
> This endpoint is processed asynchronously by a separate worker, under the existing SLA. A `202` only confirms the request was accepted — it doesn't confirm the change has taken effect yet. Poll [Get Subscription Preferences](https://moengage.com/docs/api/subscription-preferences/get-subscription-preferences-v5.md) for the same identifier and confirm the returned state matches what you sent.

> **Is the is\_globally\_unsubscribed field optional?**
>
> No — it's required on every call, since it has no neutral default: `true` unsubscribes the profile from every category on the channel, `false` explicitly clears an existing global unsubscribe.

> **What happens to categories I don't include in the request?**
>
> They're left unchanged. `categories` is a sparse map — only the category names present in the request are updated.

> **What happens if I reuse an Idempotency-Key with a different request body?**
>
> The call fails with `409`. Reusing the same key with the same body, however, returns the original response without reapplying the update.

> **If channel is omitted, which categories does the update apply to?**
>
> It defaults to `email`, the only channel this API supports at present, so the update applies to the user's email subscription categories.

> **Are there reserved event\_attributes names?**
>
> No — any attribute name is accepted. The only limits are a maximum of 5 attributes per call, names of 50 characters or fewer, and values of 255 characters or fewer.

## Postman Collection

Test these endpoints quickly by importing our Postman collection: [**View in Postman**](https://www.postman.com/moengage-dev/api-docs/collection/uorepia/moengage-subscription-categories-v5-api)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.