npm package: @notiflows/client
Description: Notiflows JavaScript SDK for the User API
Author: Notiflows
Latest version: 0.2.1

# @notiflows/client

Official JavaScript SDK for the Notiflows User API.

## Installation

```bash
npm install @notiflows/client
# or
pnpm add @notiflows/client
# or
yarn add @notiflows/client
```

## Quick Start

```typescript
import { Notiflows } from '@notiflows/client'

const notiflows = new Notiflows({
  apiKey: 'pk_your_public_key',
  userId: 'user_123',
  userKey: 'jwt_token_here',
})

// Get user's feed
const feed = notiflows.feed({ channelId: 'in_app' })
const entries = await feed.getEntries()

// Mark notification as read
await feed.markAsRead('entry_id')

// Subscribe to real-time updates
feed.onDelivery = (entry) => {
  console.log('New notification:', entry)
}
await feed.subscribeToRealtimeNotifications()

// Manage preferences
const preferences = notiflows.userPreferences()
const prefs = await preferences.get()
await preferences.update({
  channel_types: {
    email: false,
  },
})
```

## Authentication

The SDK requires three credentials:

- `apiKey` - Your public API key (starts with `pk_`)
- `userId` - The user's external ID
- `userKey` - JWT token signed with your Application Signing Key

See [Authentication Docs](https://docs.notiflows.com/api/user/authentication) for details on generating JWT tokens.

## API Reference

### Notiflows

Main client class.

```typescript
const notiflows = new Notiflows({
  apiKey: string,
  userId: string,
  userKey: string,
  apiUrl?: string,  // default: https://api.notiflows.com/user/v1
  wsUrl?: string,   // default: wss://api.notiflows.com/ws/v1
})
```

### Feed

```typescript
const feed = notiflows.feed({ channelId: 'in_app' })

// Fetch entries with optional filters
await feed.getEntries({
  status?: 'unseen' | 'seen' | 'unread' | 'read' | 'archived',
  notiflow?: string,    // filter by notiflow handle
  topic?: string,       // filter by topic
  archived?: boolean,   // include archived entries (default: false)
  limit?: number,
  after?: string,       // cursor for pagination
  before?: string,
})

// Feed settings (e.g. branding)
const settings = await feed.getSettings()
console.log(settings.branding_required)

// Update single entry
await feed.markAsSeen(entryId)
await feed.markAsRead(entryId)
await feed.markAsClicked(entryId)
await feed.markAsArchived(entryId)
await feed.markAsUnarchived(entryId)

// Batch update
await feed.batchMarkAsRead([entryId1, entryId2])
await feed.batchMarkAsArchived([entryId1, entryId2])
await feed.batchMarkAsUnarchived([entryId1, entryId2])

// Real-time
feed.onDelivery = (entry) => { ... }
feed.subscribeToRealtimeNotifications()
feed.stop()
```

### Preferences

```typescript
const preferences = notiflows.userPreferences()

await preferences.get()
await preferences.update({ ... })
```

## Error Handling

The SDK provides typed errors:

```typescript
import {
  BadRequestError,
  UnauthenticatedError,
  ForbiddenError,
  NotFoundError,
  RateLimitedError,
  isApiError,
} from '@notiflows/client'

try {
  await feed.getEntries()
} catch (error) {
  if (isApiError(error)) {
    console.log(error.code, error.message, error.details)
  }
}
```

## Documentation

Full documentation is available at [notiflows.com/docs/sdks/client-side/javascript](https://notiflows.com/docs/sdks/client-side/javascript).

## License

MIT