Pass these to inbox(options) in your better-auth config. Every option is optional.
inbox options
| Option | Type | Default | Meaning |
|---|---|---|---|
appUrl |
string | Your app’s origin. Channels join a relative href onto it |
|
channels |
Record<string, InboxChannel> |
{} |
Delivery channels beyond the in-app inbox, by name |
routes |
Record<type, DeliveryRule[]> |
{} |
Which channels each type goes to. "*" is the fallback; a type with no rule stays in-app |
shouldDeliver |
({ notification, user, channel }) => boolean | Promise<boolean> |
Return false to skip a delivery, e.g. from your own preferences |
|
presenceWindow |
number (ms) | 120000 |
How recently a user must have polled to count as in the app |
maxAttempts |
number | 5 |
Sends tried before a delivery is marked failed |
batchSize |
number | 100 |
Deliveries per processDeliveries call |
maxFanout |
number | 1000 |
Most members one organization notify may reach |
organizationCleanup |
boolean | true |
Delete notifications when an org is deleted or a member is removed or leaves |
schema |
Rename tables and fields |
organizationCleanup: false keeps an org’s and a member’s notifications when they’re removed, for example for an audit trail. deleteOrganizationData and deleteMemberData still work when it’s off. See Notify an organization.
| Option | Type | Default | Meaning |
|---|---|---|---|
onEvent |
ByoEventHandler |
Receives notifications.* events after the write commits. Errors are logged, never thrown. See Events |
|
organizationCleanup |
boolean | true |
Off also leaves notifications out of @byo-oss/core’s deleteOrganizationData/deleteMemberData fan-out |
batchSize |
number | 100 |
An integer from 1 to 1000; inbox() throws otherwise |
Don’t turn organizationCleanup off to avoid the plugin’s cleanup and core’s fan-out both running: the second run finds nothing and does nothing. Off means nothing deletes the rows.
A routes key that starts with notifications. throws when the plugin is created: those are the plugin’s own event types.
For the schema option, see Schema.
channels takes any InboxChannel, by name. The built-in email channel is mailerChannel, from @byo-oss/notifications/mailer, which sends through any Mailer from @byo-oss/mailer. See Email if unread. wrapsEmail is deprecated.
DeliveryRule
Each routes entry is a list of these.
| Field | Type | Default | Meaning |
|---|---|---|---|
channel |
string | A name from channels |
|
ifUnreadAfter |
{ seconds?, minutes?, hours? } |
Send only if still unread and unseen after this long. Omit to send right away | |
sendNowIfAway |
boolean | true |
With ifUnreadAfter, send at once when the user isn’t in the app |
cancelIfRead |
boolean | true |
Skip the send when the notification was read or seen first |
throttle |
{ seconds?, minutes?, hours? } |
At most one send of this type per user per window |
For how these behave, see Email if unread.