Skip to main content
Technology & EngineeringNotification Services175 lines

Knock

Implement Knock notification infrastructure for multi-channel delivery. Covers workflow orchestration, in-app feeds, email, push, SMS, and Slack channels with preference management and batching.

Quick Summary28 lines
You are a notification infrastructure engineer who integrates Knock into projects. Knock is a multi-channel notification platform that orchestrates delivery across in-app feeds, email, push, SMS, Slack, and webhooks from a single API call. It provides workflow logic (delays, batching, conditions), per-user preferences, and a prebuilt React feed component. Knock separates notification logic from application code, making it manageable as notification complexity grows.

## Key Points

- **Channel routing in app code**: Let Knock workflows handle channel selection; your app should only trigger workflows.
- **Skipping user identification**: Always `identify` users before triggering; inline recipient data leads to stale profiles.
- **Polling the feed API**: Use Knock's real-time WebSocket feed via the React SDK instead of polling.
- **Ignoring tenant isolation**: Multi-tenant apps should pass `tenant` on triggers so preferences and branding are scoped correctly.
- Applications needing multi-channel notifications (in-app + email + push + SMS)
- Products requiring a prebuilt in-app notification feed with real-time updates
- Teams that want non-engineers to manage notification routing and templates
- SaaS platforms needing per-user and per-tenant notification preferences
- Systems where notification batching and digest logic is critical

## Quick Example

```bash
npm install @knocklabs/node @knocklabs/react
```

```env
KNOCK_API_KEY=sk_live_your_secret_key
KNOCK_SIGNING_KEY=your_signing_key
NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY=pk_live_your_public_key
NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID=your_feed_channel_id
```
skilldb get notification-services-skills/knockFull skill: 175 lines
Paste into your CLAUDE.md or agent config

Knock

You are a notification infrastructure engineer who integrates Knock into projects. Knock is a multi-channel notification platform that orchestrates delivery across in-app feeds, email, push, SMS, Slack, and webhooks from a single API call. It provides workflow logic (delays, batching, conditions), per-user preferences, and a prebuilt React feed component. Knock separates notification logic from application code, making it manageable as notification complexity grows.

Core Philosophy

Workflow-Driven Architecture

Knock uses workflows as the unit of notification logic. A workflow defines which channels to notify, in what order, with what delays and conditions. Your application code triggers a workflow with recipients and data — it never decides the routing. This separation means product managers can adjust notification behavior in the Knock dashboard without code changes.

Preferences Belong to Users

Every notification system eventually needs user preferences. Knock provides a built-in preference model per user and per tenant. Instead of building your own preferences table and filtering logic, use Knock's preference API. Users can opt out of specific workflow categories or channels, and Knock respects these at delivery time automatically.

Batch to Reduce Noise

Individual event notifications create inbox fatigue. Knock workflows support batching windows — collecting multiple triggers into a single notification. A "5 new comments on your post" message is better than 5 separate notifications. Configure batching in the workflow, not in your application code.

Setup

Install

npm install @knocklabs/node @knocklabs/react

Environment Variables

KNOCK_API_KEY=sk_live_your_secret_key
KNOCK_SIGNING_KEY=your_signing_key
NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY=pk_live_your_public_key
NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID=your_feed_channel_id

Key Patterns

1. Trigger a Workflow

Do:

import { Knock } from "@knocklabs/node";

const knock = new Knock(process.env.KNOCK_API_KEY!);

await knock.workflows.trigger("new-comment", {
  recipients: [commentedPostAuthorId],
  actor: commentAuthorId,
  data: {
    postTitle: post.title,
    commentBody: comment.body,
    postUrl: `https://app.example.com/posts/${post.id}`,
  },
  tenant: organizationId,
});

Not this:

// Deciding channels in application code defeats workflow orchestration
if (user.preferences.email) await sendEmail(user, data);
if (user.preferences.push) await sendPush(user, data);
if (user.preferences.slack) await sendSlack(user, data);

2. Identify Users

Do:

await knock.users.identify(user.id, {
  name: user.name,
  email: user.email,
  phone_number: user.phone,
  avatar: user.avatarUrl,
});

Not this:

// Passing user data inline on every trigger
await knock.workflows.trigger("welcome", {
  recipients: [{ id: user.id, name: user.name, email: user.email }],
  // Works but duplicates user data on every call
});

3. In-App Feed Component

Do:

import {
  KnockProvider,
  KnockFeedProvider,
  NotificationIconButton,
  NotificationFeedPopover,
} from "@knocklabs/react";
import { useState, useRef } from "react";

function NotificationBell({ userId }: { userId: string }) {
  const [isVisible, setIsVisible] = useState(false);
  const buttonRef = useRef<HTMLButtonElement>(null);

  return (
    <KnockProvider apiKey={process.env.NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY!} userId={userId}>
      <KnockFeedProvider feedId={process.env.NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID!}>
        <NotificationIconButton ref={buttonRef} onClick={() => setIsVisible(!isVisible)} />
        <NotificationFeedPopover buttonRef={buttonRef} isVisible={isVisible} />
      </KnockFeedProvider>
    </KnockProvider>
  );
}

Not this:

// Building a custom feed from scratch with polling
useEffect(() => {
  const interval = setInterval(async () => {
    const notifs = await fetch("/api/notifications");
    setNotifications(await notifs.json());
  }, 5000);
  return () => clearInterval(interval);
}, []);

Common Patterns

Setting User Preferences

await knock.users.setPreferences(userId, {
  channel_types: { email: true, sms: false, push: true },
  workflows: {
    "marketing-digest": { channel_types: { email: false } },
  },
});

Sending to Multiple Recipients with Subscriptions

await knock.objects.addSubscriptions("projects", projectId, {
  recipients: memberIds,
  properties: { role: "collaborator" },
});

await knock.workflows.trigger("project-update", {
  recipients: [{ collection: "projects", id: projectId }],
  data: { updateType: "milestone_completed" },
});

Cancelling a Scheduled Workflow

await knock.workflows.cancel("payment-reminder", {
  recipients: [userId],
  cancellation_key: `invoice-${invoiceId}`,
});

Anti-Patterns

  • Channel routing in app code: Let Knock workflows handle channel selection; your app should only trigger workflows.
  • Skipping user identification: Always identify users before triggering; inline recipient data leads to stale profiles.
  • Polling the feed API: Use Knock's real-time WebSocket feed via the React SDK instead of polling.
  • Ignoring tenant isolation: Multi-tenant apps should pass tenant on triggers so preferences and branding are scoped correctly.

When to Use

  • Applications needing multi-channel notifications (in-app + email + push + SMS)
  • Products requiring a prebuilt in-app notification feed with real-time updates
  • Teams that want non-engineers to manage notification routing and templates
  • SaaS platforms needing per-user and per-tenant notification preferences
  • Systems where notification batching and digest logic is critical

Install this skill directly: skilldb add notification-services-skills

Get CLI access →

Related Skills

Magicbell

Build with MagicBell for embeddable notification inboxes and multi-channel delivery. Covers the notification inbox UI component, real-time WebSocket updates, server-side sending, user preferences, and category management.

Notification Services211L

Notifee

Integrate Notifee for robust local notification management within your React Native applications. This service provides a comprehensive cross-platform API for displaying, interacting with, and managing notifications, enhancing user engagement without relying on remote push services.

Notification Services307L

Ntfy

Implement ntfy.sh for simple HTTP-based pub/sub push notifications. Covers publishing messages via HTTP PUT/POST, subscribing via SSE and WebSocket, authentication, attachments, and self-hosted server configuration.

Notification Services209L

Pushbullet

Integrate Pushbullet to send real-time notifications, links, and files across all your devices and to other Pushbullet users. It's ideal for personal alerts, devops monitoring, IoT device notifications, or simple user-to-user communication.

Notification Services155L

Pushover

Pushover provides a simple, reliable API for sending real-time notifications to your devices. It's ideal for developers who need to send critical alerts, system status updates, or any time-sensitive information directly to a user's phone, tablet, or desktop via their dedicated app.

Notification Services159L

Roost

Integrate Roost for real-time web push notifications directly from your web application. This service simplifies subscriber management, permission handling, and message delivery, allowing you to re-engage users without requiring a native app.

Notification Services278L