Channel Subscriptions
Managing per-device push subscriptions for web push and other subscription-based channels
Channel Subscriptions
Channel subscriptions store individual push subscriptions for a user on a given channel. Unlike channel settings, which hold a single blob of configuration per user-channel pair, channel subscriptions are designed for cases where a user has multiple independent subscriptions — each with its own lifecycle.
The primary use case today is web push, where each browser or device creates its own push subscription that can be added or removed independently.
Why Separate from Channel Settings?
Push subscriptions have fundamentally different characteristics than channel settings:
| Channel Settings | Channel Subscriptions | |
|---|---|---|
| Cardinality | One per user-channel pair | Many per user-channel pair |
| Lifecycle | Set once, replaced on update | Each subscription added/removed independently |
| Semantics | Upsert (replace entire blob) | Individual add/remove operations |
| Use case | Device tokens, chat connections | Browser push subscriptions |
A user might have web push subscriptions from Chrome on their laptop, Firefox on their desktop, and Safari on their phone. Each subscription has its own endpoint and encryption keys, and removing one shouldn't affect the others.
How Channel Subscriptions Work
Each channel subscription is stored as a separate record with:
| Field | Description |
|---|---|
identifier | A unique key for deduplication (for web push, the push service endpoint URL) |
settings | Provider-specific data as JSON (for web push, endpoint, p256dh, and auth) |
When a notiflow reaches a web push channel step, Notiflows:
- Loads all channel subscriptions for the recipient on that channel
- Sends the notification to every registered subscription
- Each browser/device receives the push independently
If a user has no subscriptions for a channel, delivery through that channel is skipped.
Managing Subscriptions
Adding a Subscription
Register a subscription by sending a POST request with an identifier and provider-specific settings:
POST /user/v1/channels/<channel-id>/subscriptions
{
"identifier": "https://fcm.googleapis.com/fcm/send/...",
"settings": {
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"p256dh": "BOxxx...",
"auth": "xxx..."
}
}| Field | Type | Description |
|---|---|---|
identifier | string | Unique key for this subscription. For web push, the push endpoint URL. |
settings | object | Provider-specific data, validated per channel type. |
settings.endpoint | string | The push service endpoint URL from PushSubscription. |
settings.p256dh | string | The P-256 Diffie-Hellman public key from PushSubscription.keys. |
settings.auth | string | The authentication secret from PushSubscription.keys. |
Deduplication: If a subscription with the same identifier already exists, the settings are updated in place. No duplicate is created. This makes it safe to re-register on every page load.
Limit: A maximum of 25 subscriptions per user-channel pair is enforced.
Removing a Subscription
Remove a specific subscription by sending a DELETE request with its identifier:
DELETE /user/v1/channels/<channel-id>/subscriptions
{
"identifier": "https://fcm.googleapis.com/fcm/send/..."
}Only the matching subscription is removed — other subscriptions for the same user and channel are unaffected.
Full Integration Example
See the Web Push setup guide for a complete example of registering a service worker, subscribing to push, and sending the subscription to Notiflows.
// After getting browser push permission
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: '<your-vapid-public-key>',
});
const { endpoint, keys } = subscription.toJSON();
// Register with Notiflows
await fetch('https://api.notiflows.com/user/v1/channels/<channel-id>/subscriptions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-notiflows-api-key': '<your-public-api-key>',
'x-notiflows-user-key': '<user-jwt-token>',
},
body: JSON.stringify({
identifier: endpoint,
settings: {
endpoint,
p256dh: keys.p256dh,
auth: keys.auth,
},
}),
});When to Add Subscriptions
- After the user grants notification permission and
PushManager.subscribe()succeeds - On each page load — re-check the existing subscription and re-register it (the upsert ensures no duplicates)
- After a subscription changes (browsers can rotate push subscriptions)
When to Remove Subscriptions
- When the user explicitly opts out of push notifications in your app
- When a push delivery fails with a
410 Gonestatus (the subscription has expired) - When the user logs out and you want to stop sending them notifications on that browser