A User represents a person who may need to be notified of some action occurring in your product.
The benefits of the Knock user model
If you're used to sending notifications via single-channel APIs, the idea of storing user data in a messaging platform such as Knock may sound odd to you.
Here are a few reasons why we store user data in Knock:
- Multi-channel notifications. When you're using a single-channel API, you can pass through the recipient's email address or phone number when you trigger a message. In a multi-channel platform like Knock, that would mean passing through all of a user's channel information every time you trigger a notification. By keeping a user model in Knock, you can update a user's channel information once, then reference them via their user ID from that point on. We take care of the rest.
- Stateful in-app notifications. The Knock Feed API returns a stateful feed of the in-app notifications a given user has received from your product. The Knock user model is used to store a given user's notification feed and to give you a way to retrieve that feed via the user identifier you keep for them in your product.
- Preferences model. The Knock user model enables advanced functionality such as preferences support, where you store a given user's notification preferences in Knock and we reference that user's preferences during the run of a given notification workflow.
- Leverage user traits in notification templates. The Knock user model also enables you to store custom traits on a given user that you can reference in a notification template. This is helpful when you want to add conditional copy to a notification based on a user's role or plan.
We do not take storing your user data lightly. You can learn more about our security posture and best practices on our security page.
Sending user data to Knock
We support three approaches for sending your user data to Knock: individual identification, bulk identification, and inline identification.
In all three cases, we manage your user data via upsertion. In other words, we provide a single set of APIs for both creating new users in Knock and updating existing user data.
1. Individual identification
You can use the identify user API to send us data for a single user. If you've used a Customer Data Platform (CDP) like Segment before, this will be familiar to you.
2. Bulk identification
You can use the bulk identify API to send us data for many users at once. This endpoint allows you to identify up to 100 users at a time.
3. Inline identification
Lastly, you can also integrate user identification into your workflow trigger calls. Rather than provide a list of user ids in the
recipients field, you can instead provide a list of maps of user metadata. Knock will perform an asynchronous action to identify these users as part of processing the workflow.
See below for further discussion on how and when to identify users in Knock.
The user identifier
The identifier for a user is important as it's the unique key that we will use to merge users and determine recipients for a notification. Generally, the best practice here is to use your internal identifier for your users as the
The following attributes are required for each user you identify with Knock.
|id||An identifier for this user from your system, should be unique|
The following attributes are optional, depending on the channel types you decide to use with Knock.
|The primary email address for the user (required for email channels)|
|name||The full name of the user|
|avatar||A URL for the avatar of the user|
|phone_number||The E.164 phone number of the user (required for SMS channels)|
Storing user traits
In addition to the system attributes defined on the user schema above, Knock will keep track of any
properties (key/value pairs) that you send to us. These traits are always merged onto a user and returned to you.
Traits are useful for when you need to perform additional personalization on a user, like denormalizing the current plan they're on so you can use this to determine the portion of a notification they should receive.
You can nest the properties you send as deeply as you like, but please remember that we will not deep merge these keys.
The user object
Once sent to Knock, the user object returned to you in the Knock payload looks like this:
|id||The unique user identifier|
|properties*||Traits sent for the user are merged back onto the main user object|
|created_at||The created at time (provided by you)|
|updated_at||The last time we updated the user|
* All properties appear at the top level of the user object.
When to identify users in Knock
Knock provides a flexible set of APIs for you to manage your user data as you scale with us. Ultimately, it's up to you to decide upon the best approach for how you manage your user data with Knock.
Below we discuss some common scenarios to consider.
Initial setup: inline vs. bulk identification
When you're first getting started with Knock, you'll likely have a number of existing users that you want to migrate into Knock. If you're looking to get started with Knock quickly, you can use inline identification to start calling your workflows without any prerequisite calls to the Knock API.
If you first want to get all your users into Knock, the easiest path forward would be via our bulk identification flow.
Identifying users on an ongoing basis: jobs vs. inline identification
Once you've migrated your current users into Knock, you'll want to continue to update this data in Knock for two key cases:
- When new users sign up for your product.
- When Knock-relevant data about a user changes, like a name or an email address.
One common approach is to make subsequent calls to the Knock's user identify API following such events. For example, you could do this via a deferred job in your backend systems.
Another option is to offload these updates to your workflow trigger calls via inline identification. If you always send Knock the full set of data for your users via workflow trigger calls, you can keep your user data up to date in Knock without any additional handling on your end.
Users can be retrieved from Knock to see the current state of their properties using the
Users can be deleted from Knock via the
users.delete method. Deleting a user from Knock will have the following effect:
- The user will no longer be able to be a recipient or an actor in a workflow
- The user will no longer appear in the dashboard under the "Users" list
- Any in-app messages that reference the user will be replaced by a "missing user" marker
You might run into the scenario where you've identified an invited user to send them a notification and then that user "graduates" to a fully fledged user after they sign up, leaving you with two users in Knock. That's where the merge users method comes in handy.
Merging two users will merge the
secondary user (the invited user in our example) into the
primary user (the signed up user), and the secondary user will be deleted in the process.
Please note that merging is a destructive operation and cannot be undone.
- Properties: Properties are deep merged, but if there are any conflicts between the secondary and primary user then the value is selected from the primary user.
- Preferences: Preference sets are shallow merged between the users. Any preference sets that don't exist on the primary from the secondary are added.
- Channel data: Channel data is shallow merged from the secondary to the primary. Any channel data that doesn't exist on the primary from the secondary is added, determined by the channel_id.
- Message history: The past 30 days of message history of the secondary user will now be owned by the primary recipient.
- Activities: Any activities from the past 30 days that the secondary user was an
recipientof will be transferred to the primary user.
If you need to retain more than 30 days worth of history, please contact us.
Frequently asked questions
What do I do if my notification recipients aren't yet users?
Commonly you'll want to send notifications to entities in your system that are not currently registered users in your product (think guests or invited users). In these situations we recommend:
- Identifying the user with a unique identifier, such as their email address, or with a prefix (
guest_) to denote the different type.
- Where possible, if the notified user becomes a registered user in your system then using our merge API to merge the guest user and the registered user to preserve message sending history.
It might feel counterintuitive to store registered users and non-registered users under a single collection in your Knock environment, but Knock should always be viewed as a cache of information about users and entities that may need to be notified in your system.
Are users unique per environment?
Yes, they are. Each environment has a separate, isolated set of users. If you need to share users across environments, you must re-identify them in each environment.
What do I do if I have different types of users?
If you want to store and notify different types of users within your Knock environment, we recommend prefixing the id with the type. So if you had two distinct user types,
customers you can pass Knock ids like
How can I send a notification to a non-user entity?
If you need to send a notification to an entity in your system you should have a look at modelling those as Objects. Objects can represent any non-user entity.
Why do I see my team members as users in Knock?
When you add new team members in the Knock dashboard, we automatically add those as "Users" within your Knock development environment so can send the notifications. We do this to help you with testing.
Can I avoid storing user data in Knock?
No, all users who are sent a notification are identified in your Knock environment and are persisted. If you have a use case here that you wish to discuss with us please get in touch.