> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cskn.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Notifications

> Ask for permission, schedule local notifications, set the badge and read your app's inbox.

```tsx theme={null}
import { useNotifications } from '@cskn/sdk';

function Reminder() {
  const notifications = useNotifications();

  const remind = async () => {
    const granted = await notifications.requestPermission();
    if (!granted) return;

    const { id, error } = await notifications.schedule({
      title: 'Reminder',
      body: 'Time to stretch',
      seconds: 60 * 30,
    });
    if (error) console.warn(error);
  };

  return <button onClick={remind}>Remind me in 30 minutes</button>;
}
```

## Permission

`requestPermission()` resolves `true` when the user allows notifications. It must be called from a user gesture such as a click.

* **In a shell**, the shell asks the operating system, and the device's push token does the rest.
* **In a browser**, it subscribes this browser to Web Push for your app's origin. See [Web Push](/sdk/native/web-push) for what that can and cannot do, notably on iOS.

## Local notifications

`schedule(payload)` resolves `{ id }` on success. Keep the id to cancel it later.

<ParamField path="title" type="string" required>Notification title.</ParamField>
<ParamField path="body" type="string">Notification text.</ParamField>
<ParamField path="seconds" type="number | null">Delay before it fires. `null` fires immediately.</ParamField>
<ParamField path="repeats" type="boolean" default="false">Repeat at the same interval.</ParamField>
<ParamField path="data" type="Record<string, any>">Payload delivered with the notification.</ParamField>
<ParamField path="sound" type="boolean" default="true">Play the notification sound.</ParamField>

`cancel(id)` cancels one; `cancelAll()` cancels all of your app's scheduled notifications.

<Note>
  Scheduling is shell-only. A web page has no dependable way to ask the system to wake it at a given time, so in a browser `schedule` resolves `{ error: 'unsupported' }`. Send the notification from your server instead.
</Note>

## Badge

```tsx theme={null}
notifications.setBadgeCount(3); // 0 removes it
const count = await notifications.getBadgeCount();
```

In a browser the badge only shows on an installed web app, since a tab has no icon to badge.

## Inbox

The inbox lists the notifications the platform delivered to the user **from your app**. The shell scopes it to your app, so you never see another app's notifications.

```tsx theme={null}
const { notifications: items, unreadCount } = await notifications.getInbox();
notifications.markInboxRead(items[0].id); // or markInboxRead() for all
```

Each item is `{ id, senderSlug, title, body?, data?, read, createdAt }`. When `data` holds `{ path, params }`, tapping the notification opens that route in your app.

In a browser the inbox is always empty.

## Functions

`requestNotificationPermission`, `scheduleNotification`, `cancelNotification`, `cancelAllNotifications`, `getBadgeCount`, `setBadgeCount`, `getNotificationInbox`, `markInboxRead`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.