# Subscriptions for notifications Subscriptions send notifications to a message queue of your choice when a resource is modified. You can use notifications to trigger asynchronous background processes such as sending an order confirmation email, charging a credit card after an order has shipped, or synchronizing customer accounts to a customer relationship management (CRM) system. Subscriptions work in the following way: 1. You create a Subscription and provide details of the message queue, also known as the Destination, where you want to receive the notifications. When you create, update, or delete a Subscription, it can take up to one minute for the change to take effect. For more information about this, see [Eventual Consistency](/api/general-concepts.md#eventual-consistency). 2. The API sends a test notification to your queue to make sure the Destination is configured correctly. 3. When a change occurs to the resource you've subscribed to, the API sends the notification to the Destination. For information about how we handle the order messages are delivered and our delivery guarantees, see [Delivery](/api/projects/subscriptions.md#delivery). A notification is sent to the Destination as a payload of one of the following types: - **Message** - This payload contains one of our predefined [Messages](/api/projects/messages.md). - **Change** - This payload contains information about the [change to the resource](/api/projects/subscriptions.md#changesubscription) and differs depending on if the resource was created, updated, or deleted. - **Event** - This payload contains one of our predefined [Events](/api/events.md). 4. Your integration uses the notification to trigger your background process. A maximum of **50** Subscriptions can be created per Project. This is a soft limit that can be increased per Project after a performance impact review. See [Limit increase guidance](/api/limit-increase-guidance.md#extensibility-and-eventing-limits). Learn more about API Subscriptions in our self-paced [Extensibility overview](/learning-model-your-business-structure/extensibility/overview.md) and [Integration patterns](/learning-integrate-with-commercetools/integration-patterns/overview.md) modules. ## Representations #### Subscription [type definition](/search.md?urn=ctp:api:type:Subscription). #### SubscriptionDraft [type definition](/search.md?urn=ctp:api:type:SubscriptionDraft). #### SubscriptionPagedQueryResponse [type definition](/search.md?urn=ctp:api:type:SubscriptionPagedQueryResponse). #### Destination The API supports the following messaging services: - [AWS SQS](https://aws.amazon.com/sqs/), [AWS SNS](https://aws.amazon.com/sns/), [AWS EventBridge](https://aws.amazon.com/eventbridge/) - [Azure Service Bus](https://azure.microsoft.com/en-us/products/service-bus/), [Azure Event Grid](https://azure.microsoft.com/en-us/products/event-grid/) - [Google Cloud Pub/Sub](https://cloud.google.com/pubsub/) - [Confluent Cloud](https://www.confluent.io/confluent-cloud/) Messaging services are differentiated by the `type` field. ##### SQSDestination [type definition](/search.md?urn=ctp:api:type:SqsDestination). ##### SNSDestination [type definition](/search.md?urn=ctp:api:type:SnsDestination). ##### EventBridgeDestination [type definition](/search.md?urn=ctp:api:type:EventBridgeDestination). ##### AzureServiceBusDestination [type definition](/search.md?urn=ctp:api:type:AzureServiceBusDestination). To grant access to resources, Azure Service Bus uses the concept of [Shared Access Policies](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-sas). Shared Access Policy is defined on a scope and includes certain permissions. For setting up an Azure Service Bus Subscription, you must create a Shared Access Policy on your queue/topic and include the `Send` permission. When you open the policy in the Azure Portal, you will find that Azure has generated two connection strings for your policy. A connection string has the following format: `Endpoint=sb://.servicebus.windows.net/;SharedAccessKeyName=;SharedAccessKey=;EntityPath=` You can set either of the two connection strings in the `connectionString` attribute of an Azure Service Bus Destination. Ensure that the path points to your queue/topic. ##### AzureEventGridDestination [type definition](/search.md?urn=ctp:api:type:AzureEventGridDestination). ##### GoogleCloudPubSubDestination [type definition](/search.md?urn=ctp:api:type:GoogleCloudPubSubDestination). commercetools Projects hosted on Google Cloud can benefit from additional security by enabling [Google Cloud's VPC Service Controls](https://cloud.google.com/security/vpc-service-controls). This ensures that Google Cloud Pub/Sub Destinations can only be accessed from the commercetools Google Cloud infrastructure. To configure VPC Service Controls, specify the commercetools GCP project number as the source of your ingress policy rule. You can optionally select `subscriptions@commercetools-platform.iam.gserviceaccount.com` as the identity of the ingress policy for an added layer of security. To obtain the required commercetools GCP project number, contact your Customer Success Manager. ##### ConfluentCloudDestination [type definition](/search.md?urn=ctp:api:type:ConfluentCloudDestination). #### AwsAuthenticationMode [type definition](/search.md?urn=ctp:api:type:AwsAuthenticationMode). #### MessageSubscription [type definition](/search.md?urn=ctp:api:type:MessageSubscription). ##### MessageSubscriptionResourceTypeId [type definition](/search.md?urn=ctp:api:type:MessageSubscriptionResourceTypeId). #### ChangeSubscription [type definition](/search.md?urn=ctp:api:type:ChangeSubscription). ##### ChangeSubscriptionResourceTypeId [type definition](/search.md?urn=ctp:api:type:ChangeSubscriptionResourceTypeId). #### EventSubscription [type definition](/search.md?urn=ctp:api:type:EventSubscription). ##### EventSubscriptionResourceTypeId [type definition](/search.md?urn=ctp:api:type:EventSubscriptionResourceTypeId). #### SubscriptionHealthStatus [type definition](/search.md?urn=ctp:api:type:SubscriptionHealthStatus). The health of the delivery infrastructure is independent of the `SubscriptionHealthStatus` and can be checked on the [status page](https://status.commercetools.com/). #### DeliveryFormat The format in which the payload is delivered. Defaults to [PlatformFormat](/api/projects/subscriptions.md#platformformat). ##### PlatformFormat [type definition](/search.md?urn=ctp:api:type:PlatformFormat). ##### CloudEventsFormat [type definition](/search.md?urn=ctp:api:type:CloudEventsFormat). ## Get Subscription ### Get Subscription by ID [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/{id}:GET). ### Get Subscription by Key [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/key={key}:GET). ### Get Health Status of Subscription by ID [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/{id}/health:GET). The HTTP status codes are mapped to the [SubscriptionHealthStatus](/api/projects/subscriptions.md#subscriptionhealthstatus) as follows: - `200` - `Healthy` - `400` - `ConfigurationError`, `ConfigurationErrorDeliveryStopped`, and `ManuallySuspended` - `503` - `TemporaryError` ## Query Subscriptions [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions:GET). ## Check if Subscription exists ### Check if Subscription exists by ID [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/{id}:HEAD). ### Check if Subscription exists by Key [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/key={key}:HEAD). ### Check if Subscription exists by Query Predicate [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions:HEAD). ## Create Subscription [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions:POST). ## Update Subscription ### Update Subscription by ID [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/{id}:POST). ### Update Subscription by Key [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/key={key}:POST). ## Update actions #### Set Key [type definition](/search.md?urn=ctp:api:type:SubscriptionSetKeyAction). #### Set Messages [type definition](/search.md?urn=ctp:api:type:SubscriptionSetMessagesAction). #### Set Changes [type definition](/search.md?urn=ctp:api:type:SubscriptionSetChangesAction). #### Set Events [type definition](/search.md?urn=ctp:api:type:SubscriptionSetEventsAction). #### Change Destination [type definition](/search.md?urn=ctp:api:type:SubscriptionChangeDestinationAction). ## Delete Subscription ### Delete Subscription by ID [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/{id}:DELETE). ### Delete Subscription by Key [endpoint definition](/search.md?urn=ctp:api:endpoint:/{projectKey}/subscriptions/key={key}:DELETE). ## Delivery The Delivery payload depends on the chosen [DeliveryFormat](/api/projects/subscriptions.md#deliveryformat). ### Delivery payload for the PlatformFormat [type definition](/search.md?urn=ctp:api:type:DeliveryPayload). #### MessageDeliveryPayload [type definition](/search.md?urn=ctp:api:type:MessageDeliveryPayload). If the payload fits into the size limit of your message queue (the limit is often 256 KB), all additional fields for the specific [Message](/search.md?urn=ctp:api:type:Message) are included as well (along with the `type` field). If the payload does not fit inside the limit, it can be retrieved from the [Messages Query HTTP API](/search.md?urn=ctp:api:endpoint:/{projectKey}/messages/{id}:GET) if the feature is enabled. ##### PayloadNotIncluded [type definition](/search.md?urn=ctp:api:type:PayloadNotIncluded). #### ResourceCreatedDeliveryPayload [type definition](/search.md?urn=ctp:api:type:ResourceCreatedDeliveryPayload). #### ResourceUpdatedDeliveryPayload [type definition](/search.md?urn=ctp:api:type:ResourceUpdatedDeliveryPayload). #### ResourceDeletedDeliveryPayload [type definition](/search.md?urn=ctp:api:type:ResourceDeletedDeliveryPayload). #### EventDeliveryPayload [type definition](/search.md?urn=ctp:api:type:EventDeliveryPayload). ### Delivery payload for the CloudEventsFormat [type definition](/search.md?urn=ctp:api:type:CloudEventsPayload). ### Delivery guarantees #### At-least-once delivery If no positive acknowledgment is received that a notification has been accepted by the Destination, delivery will be retried. Our Retry Policy depends on the [SubscriptionHealthStatus](/api/projects/subscriptions.md#subscriptionhealthstatus): - `TemporaryError` - Retry for up to 48 hours, after which notifications may be dropped. - `ConfigurationError` - Retry for up to 24 hours (for production Projects) or 1 hour (for development or staging Projects), after which the status changes to `ConfigurationErrorDeliveryStopped`, and notifications are dropped. A side effect of the retry is that the same notification may be sent several times. An idempotent processor that doesn't process the same notification twice can check whether it was already processed. For `notificationType` `"Message"`, use the fields `resource.id` and `sequenceNumber`. In other cases, use the field's `resource.id` and `version`. We guarantee that all notification payloads we attempt to deliver to a Destination are valid according to their specification. Therefore, the only cases where notifications can't be delivered are due to an ongoing incident, or due to a misconfiguration. You can [monitor the health of a Subscription](/api/projects/subscriptions.md#get-health-status-of-subscription-by-id) with a tool of your choice. For production-critical queues, we recommend setting up an automatic alert. #### No guarantee on order Notifications are not guaranteed to be delivered in their natural order (for example, with ascending `sequenceNumber` or ascending `version`). This is especially true in the case of retries. For `notificationType` `"Message"`, a notification processor can use the fields `resource.id` and `sequenceNumber` to process notifications in the correct order (for example, if the last processed `sequenceNumber` was `2`, and the current notification is `4`, the current notification can be put back into the queue for processing at a later point in time). For notifications of `notificationType` other than `"Message"`, the fields `resource.id`, `version` and (in case of update) `oldVersion` can be used. Note that `version` is not sequential. #### No guarantee on delivery time Notifications are not guaranteed to be delivered within a certain time frame. Although most notifications are delivered within seconds, delays of several minutes can be caused by a variety of factors, such as scaling infrastructure resources. Therefore we do not recommend using Subscriptions for time-critical use cases where a few minute's delay is seen as an incident. ## Related pages - [Area overview page with navigation](/api.md) - [Previous page: API Extensions](/api/projects/api-extensions.md) - [Next page: Messages](/api/projects/messages.md) - [Search documentation and API specs](/search.md)