# API Reference

Source: https://pushary.com/docs/web-push/client-sdk/api-reference
Last updated: 2026-05-11

> Complete API reference for the Pushary client SDK

## createPushary [#createpushary]

Creates a new Pushary instance.

```typescript
const pushary = createPushary(config: PusharyConfig): PusharyInstance
```

### PusharyConfig [#pusharyconfig]

```typescript
interface PusharyConfig {
  siteKey: string
  apiUrl?: string
  autoPrompt?: boolean
  promptDelay?: number
  debug?: boolean
  onSubscribe?: (subscription: PushSubscription) => void
  onPermissionDenied?: () => void
  onNotSupported?: () => void
  onNotificationClick?: (url: string, data: NotificationData) => boolean | void
}
```

### PusharyInstance [#pusharyinstance]

```typescript
interface PusharyInstance {
  promptForPermission(): Promise<PushSubscription | null>
  subscribe(): Promise<PushSubscription | null>
  unsubscribe(): Promise<void>
  setExternalId(externalId: string): Promise<void>
  setTags(tags: Record<string, string>): Promise<void>
  processRetryQueue(): Promise<void>
  isSupported(): boolean
}
```

## Methods [#methods]

### promptForPermission [#promptforpermission]

Requests notification permission from the user. If permission is already granted, subscribes immediately.

```typescript
const subscription = await pushary.promptForPermission()

if (subscription) {
  console.log('User subscribed:', subscription.endpoint)
} else {
  console.log('Permission denied or not supported')
}
```

### subscribe [#subscribe]

Subscribes to push notifications. Requires permission to already be granted.

```typescript
if (Notification.permission === 'granted') {
  const subscription = await pushary.subscribe()
}
```

### unsubscribe [#unsubscribe]

Unsubscribes the user from push notifications.

```typescript
await pushary.unsubscribe()
```

### setExternalId [#setexternalid]

Associates your internal user ID with the subscriber. Enables targeting by user ID from your backend.

```typescript
await pushary.setExternalId('user-123')
```

### setTags [#settags]

Sets tags for subscriber segmentation.

```typescript
await pushary.setTags({
  plan: 'premium',
  interests: 'sports,news',
})
```

### isSupported [#issupported]

Checks if push notifications are supported in the current browser.

```typescript
if (pushary.isSupported()) {
  // Push is available
}
```

## Callbacks [#callbacks]

### onSubscribe [#onsubscribe]

Called when the user successfully subscribes.

```typescript
createPushary({
  siteKey: 'pk_xxx',
  onSubscribe: (subscription) => {
    console.log('Subscribed:', subscription.endpoint)
  },
})
```

### onPermissionDenied [#onpermissiondenied]

Called when the user denies notification permission.

```typescript
createPushary({
  siteKey: 'pk_xxx',
  onPermissionDenied: () => {
    console.log('User denied notifications')
  },
})
```

### onNotificationClick [#onnotificationclick]

Called when a notification is clicked. Return `false` to prevent default navigation.

```typescript
createPushary({
  siteKey: 'pk_xxx',
  onNotificationClick: (url, data) => {
    console.log('Clicked:', url, data)
    
    if (data.campaignId === 'special') {
      window.location.href = '/special-page'
      return false
    }
    
    return true
  },
})
```

## Utility Functions [#utility-functions]

The SDK exports utility functions for common tasks like device detection and URL handling.

### isPushSupported [#ispushsupported]

Checks if push notifications are supported in the current environment.

```typescript
import { isPushSupported } from '@pushary/sdk'

if (isPushSupported()) {
  console.log('Push notifications are supported')
}
```

**Returns:** `boolean` - `true` if service workers, PushManager, and Notification API are available.

### getDeviceInfo [#getdeviceinfo]

Gets detailed information about the current device and browser.

```typescript
import { getDeviceInfo } from '@pushary/sdk'

const info = getDeviceInfo(navigator)
console.log(info)
```

**Returns:** `DeviceInfo` object with:

* `userAgent: string` - Full user agent string
* `browser: string` - Browser name (Chrome, Firefox, Safari, Edge, Opera, Unknown)
* `os: string` - Operating system (Windows, macOS, Linux, Android, iOS, Unknown)
* `deviceType: string` - Device type (desktop, mobile, tablet)
* `language: string` - Browser language
* `timezone: string` - User's timezone

### detectBrowser [#detectbrowser]

Detects the browser from a user agent string.

```typescript
import { detectBrowser } from '@pushary/sdk'

const browser = detectBrowser(navigator.userAgent)
console.log(browser)
```

**Parameters:** `userAgent: string`

**Returns:** `'Chrome' | 'Firefox' | 'Safari' | 'Edge' | 'Opera' | 'Unknown'`

### detectOS [#detectos]

Detects the operating system from a user agent string.

```typescript
import { detectOS } from '@pushary/sdk'

const os = detectOS(navigator.userAgent)
console.log(os)
```

**Parameters:** `userAgent: string`

**Returns:** `'Windows' | 'macOS' | 'Linux' | 'Android' | 'iOS' | 'Unknown'`

### detectDeviceType [#detectdevicetype]

Detects the device type from a user agent string.

```typescript
import { detectDeviceType } from '@pushary/sdk'

const deviceType = detectDeviceType(navigator.userAgent)
console.log(deviceType)
```

**Parameters:** `userAgent: string`

**Returns:** `'desktop' | 'mobile' | 'tablet'`

### navigateToUrl [#navigatetourl]

Navigates to a URL by setting `window.location.href`.

```typescript
import { navigateToUrl } from '@pushary/sdk'

navigateToUrl('https://example.com/page')
```

**Parameters:** `url: string`

**Returns:** `void`

### isNavigationValid [#isnavigationvalid]

Checks if a pending navigation is still valid (not expired).

```typescript
import { isNavigationValid } from '@pushary/sdk'

const pending = { timestamp: Date.now(), url: '/page' }
if (isNavigationValid(pending)) {
  console.log('Navigation is still valid')
}
```

**Parameters:** `pending: PendingNavigation` - Object with `timestamp` and `url`

**Returns:** `boolean` - `true` if navigation hasn't expired (within 30 seconds)

### isExternalUrl [#isexternalurl]

Checks if a URL is external (different origin).

```typescript
import { isExternalUrl } from '@pushary/sdk'

if (isExternalUrl('https://example.com', window.location.origin)) {
  console.log('External URL')
}
```

**Parameters:**

* `url: string` - URL to check
* `origin: string` - Current origin to compare against

**Returns:** `boolean` - `true` if URL has a different origin

### urlBase64ToUint8Array [#urlbase64touint8array]

Converts a base64 URL-encoded string to a Uint8Array. Useful for VAPID keys.

```typescript
import { urlBase64ToUint8Array } from '@pushary/sdk'

const vapidPublicKey = 'BEl62iUY...'
const uint8Array = urlBase64ToUint8Array(vapidPublicKey)
```

**Parameters:** `base64String: string` - URL-safe base64 string

**Returns:** `Uint8Array` - Decoded byte array

## Browser Support [#browser-support]

| Browser | Minimum Version   |
| ------- | ----------------- |
| Chrome  | 50+               |
| Firefox | 44+               |
| Safari  | 16+ (macOS & iOS) |
| Edge    | 17+               |
| Opera   | 37+               |

## Internal Endpoints [#internal-endpoints]

These endpoints are used internally by the SDK. You typically don't need to call them directly, but they're documented here for reference.

### Update Subscription [#update-subscription]

```
POST /api/v1/subscription-change
```

Updates a subscriber's push subscription endpoint when their browser subscription changes (e.g., after reinstalling the browser or clearing data).

**Used by:** The SDK automatically calls this when it detects a subscription change.

#### Request Body [#request-body]

```json
{
  "oldEndpoint": "https://fcm.googleapis.com/...",
  "newSubscription": {
    "endpoint": "https://fcm.googleapis.com/...",
    "keys": {
      "p256dh": "base64-encoded-key",
      "auth": "base64-encoded-key"
    }
  }
}
```

#### Response [#response]

```json
{
  "success": true,
  "subscriberId": "sub_abc123"
}
```

### Get Site Configuration [#get-site-configuration]

```
GET /api/v1/site/:siteSlug
```

Retrieves public site configuration including branding settings. This is used for the hosted subscription page and widget customization.

**Used by:** Subscription pages and embed widgets.

#### Response [#response-1]

```json
{
  "name": "My Site",
  "logoUrl": "https://example.com/logo.png",
  "domain": "example.com",
  "siteKey": "pk_xxx",
  "branding": {
    "primaryColor": "#007bff",
    "buttonText": "Subscribe"
  }
}
```