Announcing the subscriptions API

Today we’re announcing our new Subscriptions API.

With subscriptions, you can model lists of users, then notify all users in that list with a single API call. When you notify a list, Knock handles the efficient, concurrent fan out of all users subscribed to that list, making it possible to build lists of subscribers that can notify tens or hundreds of thousands of users.

Subscriptions are a powerful way for you to offload to Knock the responsibility of who should be notified. You can use subscriptions to power alerting use cases and publish/subscribe models, or to model the concept of a set of dynamic followers of a resource.

The subscriptions API is available today across all Knock plans. You can get started by reading the documentation.

Model any kind of user list

Subscriptions extend the functionality of Knock Objects so that one or more users can be subscribed to an object. Objects in Knock can represent any entity in your system which are unique in a collection. Here we use them to model any entity that represents a set of users, such as a list or a group of users with a particular role.

Let’s take a look at an example where we want to create a group of team members for a particular team:

// 1) Create the team member object
await knock.objects.set("team_members", team.id, {
  team_name: knock_team.name,
});

// 2) Subscribe users to the team member object
await knock.objects.addSubscriptions("team_members", team.id, {
  recipients: ["chris", "sam"],
});

Knock already supports sending notifications to non-user recipients using Objects. We’ve extended this behavior so that when you trigger a workflow with an object recipient, Knock automatically runs the workflow for each users subscribed to the object.

await knock.workflows.trigger("new-team-member-added", {
  recipients: [{ collection: "team_members", id: team.id }],
});

Subscriptions are a great way for you to offload to Knock the concept of who needs to be notified. Additionally, using subscriptions means it’s trivial to notify large groups of users with a single workflow trigger.

Supporting nested object hierarchies

Subscriptions also support nested objects as subscribers as well, which you can use to create more complex hierarchies of resources.

As an example, you can use subscriptions to model a scenario where a “team” has many “projects” and where each project has many “project members”. If we want to send a notification to all project members for a team we can do so by triggering a workflow with the top-level team as a recipient and Knock will automatically fan out to all of the subscribers of the team (the projects) and then enqueue workflows for all of the project members subscribed to each project.

Let’s take a look at this in practice:

// 1) Create our team and project
await knock.objects.set("teams", team.id, { name: team.name });
await knock.objects.set("projects", project.id, { name: project.name });

// 2) Subscribe project members to the project
await knock.objects.addSubscriptions("projects", project.id, {
  recipients: ["chris", "sam"],
});

// 3) Subscribe the project to its parent team
await knock.objects.addSubscriptions("teams", team.id, {
  recipients: [{ collection: "projects", id: project.id }],
});

// 4) Trigger a workflow for the team to notify all project members
await knock.workflows.trigger("team-update", {
  recipients: [{ collection: "teams", id: team.id }],
});

As a note, we currently support a maximum depth of 1 for nested objects. If you need to store more hierarchical data, please get in touch and we’d love to discuss your use case further.

Storing custom properties

You might also need to store additional information about the relationship between the user and the object to which they are subscribed. A good example of this: a team in which each member of that team can have a distinct role. You can use subscriptions properties to support this use case:

await knock.objects.addSubscriptions("team_members", team.id, {
  recipients: ["chris"],
  properties: { role: "ADMIN" },
});

In a future release of the subscriptions API we’ll be introducing ways that you can use these properties to target a subset of subscribers during the fan out process.

Getting started with subscriptions

The subscriptions API is available across all Knock plans starting today. You can get started by reading the documentation or API reference. If you want to see an example of subscriptions in action, we have a reference guide on how to model an alerting use case.

Frequently asked questions

Q: Is there a maximum number of recipients that can be subscribed to an object?

No, there’s no upper bound on the number of subscribers to an object.

Q: Is there a maximum number of recipients that I can store in Knock?

No, there’s no upper bound on the number of recipients that you can store within Knock.

Q: Is there any cost to creating subscriptions?:

No, we only charge on a notification-sent basis. There’s no charge to store recipients or associate those recipients with objects via a subscription.