Subscription-API
With the Catalog Subscription API, developers get access to a stream of events related to and app or team.
This documentation is intended for technical users (integrators and developers).
This documentation assumes familiarity with GraphQL. Please read the official website's Introduction to GraphQL to learn about the concepts if you have never worked with GraphQL before.
Introduction
What are Events?
When working with the Purple DS Content Cloud all actions related to content are processed by an event streaming platform. When an editor publishes a new article or and updated revision of an article, this change gets processed by our Content Pipeline and eventually lands in the database used by clients to access the contents.
What is the Subscription API?
The Subscription API is a backend service that implements GraphQL subscriptions specification. With it you can start a WebSocket connection to our backend service and get real-time delivery of Content Pipeline events.
After subscribing to events your GraphQL client will receive all events matching the query. The state is stored based on the following query parameters:
AppInfo
- appId
- preview
DeviceInfo
- deviceId
- platform
Authorization
- accessToken
- accountAccessToken
- subscriptionCodes
Specific parameters
- postId
- publicationId
- contentFilter
If any of the above mentioned parameters changes, a new subscription is created. The subscription key decides which queue a connection reads from: connections with the same key share the queue and split the events (see "Several connections with the same subscription").
The Subscription API has a latency of up to 400ms. This means that there might be a lag of 400ms between an article being available in the Catalog API ("published") and the article being delivered as an event through our Subscription API.
Delivery guarantees
Events are delivered at least once: an event counts as delivered only once it has been handed over to your WebSocket connection. If a connection ends before that, the event is sent again when you reconnect with the same subscription (same app info, device info, authorization and parameters). This state is kept for 7 days; after that, a subscription only receives new events.
What this means for your client:
- Duplicates are possible. After a reconnect, an event can arrive a second time. Use the content ID and version to recognise and skip duplicates.
- Events sent to a connection that is already broken are not repeated. If the network between your client and us breaks without the connection being closed, events can still be sent to it until the broken connection is detected.
- An update is dropped if we can't load the content for about a minute. Updates that include the content (for example publicationUpdates) are retried for about a minute; if the content still can't be loaded, that single update is skipped and the subscription continues.
Recommendation: after every reconnect, check the Content API for content changed since the last event you received. This closes the remaining gaps.
Connections and reconnects
Planned restarts (close code 1012)
When we deploy or restart the service, we close connections with the WebSocket close code 1012 (Service Restart). Reconnect right away; events that had not been handed over yet are delivered after the reconnect.
Keepalive
The server sends graphql-ws ping messages while a connection is idle. Answer each one with a pong message, as required by the graphql-transport-ws protocol (most client libraries do this automatically).
Several connections with the same subscription
Connections with the same subscription (same app info, device info, authorization and parameters) share one queue: each event goes to only one of them. If you run several instances of your client in parallel and each should receive all events, give each instance its own deviceId. A new deviceId starts with new events only and does not receive the history.
Optional, enabled per customer on request
The following two features are off by default. We enable them per customer after agreeing on it with you.
- A new connection replaces the old one. A new subscription takes over from an older one with the same subscription key, even if the older connection was not detected as broken yet. The older subscription then ends with a GraphQL error whose extensions.code is SUBSCRIPTION_SUPERSEDED. Don't reconnect on this error, or two instances with the same deviceId keep replacing each other. With this feature, every instance that should run in parallel needs its own deviceId.
- Detection of broken connections. The server sends WebSocket ping frames (RFC 6455) and closes a connection with close code 1001 (Going Away) if nothing has been received from the client for about a minute. Your client must answer ping frames with pong frames (many WebSocket libraries do this automatically; for some it has to be enabled), and reconnect after the close.
Message size
Each event is sent as a single WebSocket frame. Updates that contain the content of a post (for example publicationUpdates) can be up to 4 MB for very long articles. Make sure your client accepts frames of that size; some libraries limit frames to 64 KB by default.
Usage
Connection
The API endpoint is available at wss://catalog.purplemanager.com/subscriptions/subscriptions (Secure WebSocket connection)
A web-based schema exploration and query sandbox is available at https://catalog.purplemanager.com/subscriptions/graphiql
Changelog
Release 2026-10-19
- Planned restarts close connections with close code 1012; events not yet handed over are delivered after the reconnect. Duplicates are possible.
- Updates for very long posts (catalog responses above 256 KB) are delivered again; messages can be up to 4 MB in a single frame.
- New optional features, enabled per customer on request: a new connection replaces the older one with the same subscription ( SUBSCRIPTION_SUPERSEDED), and broken connections are detected with WebSocket ping frames and closed with code 1001.
Release 2025-05-12
📘 Taxonomy Update Behavior Change
Overview
Previously, any update to taxonomy data (e.g. renaming a category or reorganizing the structure) triggered content changed events for all affected content items. In large catalogs, this behavior could result in millions of events, overwhelming downstream systems and degrading performance.
What's New
Starting with this update, taxonomy changes no longer trigger content changed events. Instead, taxonomy updates emit a single, dedicated event:
- PublishedTaxonomyEvent for changes and initial creation
- DeletedTaxonomyEvent for deletions
This change significantly reduces the volume of events and provides a more efficient way to propagate taxonomy updates.
Required Action for Integrators
If you are using the Catalog Subscription API, and your application relies on detecting taxonomy changes to maintain data consistency, you must:
- Subscribe to PublishedTaxonomyEvent via the changes subscription type.
- Handle taxonomy updates by consuming the data provided in the taxonomy event and updating your local database or cache accordingly.
Example:
Previously, when a taxonomy was changed, you would get an updated post via postUpdates or publicationUpdates. Now, you will need to start subscribing to changes and handle PublishedTaxonomyEvent and DeletedTaxonomyEvent events.
Benefits
- Improved system scalability and reduced noise in event-driven architectures.
- Clear separation between content and taxonomy change notifications.