Skip to main content

SDK Developer API

This document describes how to use the OcmPush SDK in Manual Mode to programmatically control push notification prompts.

Table of Contents


Overview

The OcmPush SDK provides a JavaScript API for requesting push notification permissions from users. It supports multiple prompt types (slidedown, bell widget, category selector, inline, native) and can be used in either automatic or manual mode.


Installation

Embed the SDK script in your HTML:

<!-- Auto Mode (default) -->
<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer></script>

<!-- Manual Mode -->
<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>

Use the app's SDK embed URL from the dashboard install page. The current route pattern is /sdk/{app.identifier}.js.


Modes

Auto Mode

In auto mode (default), the SDK automatically shows prompts based on the server configuration. No JavaScript code is required.

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer></script>
<!-- Prompts appear automatically based on server config -->

Manual Mode

In manual mode, you control exactly when and which prompts appear. Enable manual mode by adding the data-manual attribute to the script tag.

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
// Your code here
OcmPush.showSlidedown();
OcmPush.run();
});
</script>

Important: In manual mode, you must call run() after setting up your prompts to actually display them and complete the subscription flow.


API Reference

configure()

Deep merges configuration overrides into the global SDK config. Use this to programmatically override settings from the server configuration.

configure(overrides: PartialAppConfig): OcmPushAPI

Parameters:

  • overrides - Partial configuration object to merge into the global config

Returns: The OcmPush instance for chaining.

Merge Behavior:

  • Nested objects are recursively merged
  • Arrays are replaced entirely (not merged)
  • undefined values are skipped (won't overwrite existing values)
  • Primitives and null values replace existing values

Example:

OcmPush.configure({
debugMode: true,
resubscribe_enabled: true,
resubscribe_intervals: [1, 7, 30],
});

OcmPush.run();

Alternative: Pre-script Override

You can also set overrides before the SDK script loads using window.__OCM_PUSH_OVERRIDES__:

<script>
window.__OCM_PUSH_OVERRIDES__ = {
debugMode: true,
resubscribe_enabled: true,
};
</script>
<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer></script>

Both methods use the same deep merge logic and can be used together.


run()

Executes the SDK flow: displays configured prompts, requests permission, and completes the subscription or subscription update flow.

run(): Promise<SubscriptionData>

Returns: Promise<{ userId: string, appId: string } | null>

Example:

const result = await OcmPush.run();
if (result) {
console.log('Subscribed! User ID:', result.userId);
} else {
console.log('Subscription failed or was denied');
}

showSlidedown()

Adds a slidedown prompt to the prompts queue. By default, the slidedown appears at the top-right of the page, but can be positioned using setPromptConfig().

showSlidedown(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

OcmPush.showSlidedown();
OcmPush.run();

// With custom position
OcmPush.setPromptConfig('slidedown', { position: 'bottom-right' });
OcmPush.showSlidedown();
OcmPush.run();

showBell()

Adds a bell widget to the prompts queue. The bell is a floating button that users can click to subscribe. By default appears at the bottom-right corner.

showBell(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

OcmPush.showBell();
OcmPush.run();

// With custom position and size
OcmPush.setPromptConfig('bell', { position: 'bottom-left', size: 'large' });
OcmPush.showBell();
OcmPush.run();

showCategorySlidedown()

Adds a category slidedown prompt. This allows users to select which notification categories they want to subscribe to. By default appears at the top-right, but can be positioned using setPromptConfig().

showCategorySlidedown(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

// Set categories first
OcmPush.setCategories([
{ id: 1, name: 'News', tag_key: 'news', default_checked: true },
{ id: 2, name: 'Promotions', tag_key: 'promos', default_checked: false },
]);

OcmPush.showCategorySlidedown();
OcmPush.run();

// With custom position
OcmPush.setPromptConfig('category_slidedown', { position: 'top-center' });
OcmPush.showCategorySlidedown();
OcmPush.run();

showInline()

Adds an inline prompt that renders inside a specific DOM element. Requires a selector to be configured first.

showInline(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

OcmPush.setPromptConfig('inline', { selector: '#subscribe-container' });
OcmPush.showInline();
OcmPush.run();

showNative()

Adds a native browser permission prompt. This triggers the browser's built-in permission dialog without any custom UI.

showNative(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

OcmPush.showNative();
OcmPush.run();

resetPrompts()

Clears all prompts from the queue. Use this to start fresh before adding new prompts.

resetPrompts(): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

OcmPush.resetPrompts()
.showSlidedown()
.run();

setPromptConfig()

Configures options for a specific prompt type. Options are merged with global config or defaults.

setPromptConfig(type: PromptType, options: PartialPromptConfig): OcmPushAPI

Parameters:

  • type - The prompt type: 'slidedown', 'bell', 'category_slidedown', 'inline', 'native'
  • options - Partial configuration object (see Configuration Options)

Returns: The OcmPush instance for chaining.

Example:

OcmPush.setPromptConfig('slidedown', {
action_message: 'Get notified about new posts!',
accept_button_text: 'Yes, notify me',
deny_button_text: 'Not now',
accept_button_color: '#007bff',
position: 'top-center', // or 'top-left', 'top-right', 'bottom-left', 'bottom-right'
});

OcmPush.setPromptConfig('bell', {
position: 'bottom-left', // or 'bottom-right'
size: 'large',
});

OcmPush.showSlidedown();
OcmPush.showBell();
OcmPush.run();

setCategories()

Sets the subscription categories for the category slidedown prompt.

setCategories(categories: SubscriptionCategory[]): void

Parameters:

  • categories - Array of category objects

Category Object:

{
id: number;
name: string;
tag_key: string;
description?: string;
default_checked: boolean;
}

Example:

OcmPush.setCategories([
{ id: 1, name: 'Breaking News', tag_key: 'breaking', default_checked: true },
{ id: 2, name: 'Sports', tag_key: 'sports', default_checked: false },
{ id: 3, name: 'Entertainment', tag_key: 'entertainment', default_checked: false },
]);

OcmPush.showCategorySlidedown();
OcmPush.run();

getSubscription()

Returns the current in-memory subscription data for this SDK instance.

getSubscription(): SubscriptionData

Returns: { userId: string, appId: string } | null

Note: This method returns the last subscription state emitted by the current SDK instance, typically after run() completes. It does not query the browser Push API or your backend on demand.

Example:

const subscription = OcmPush.getSubscription();
if (subscription) {
console.log('User is subscribed:', subscription.userId);
}

getPermissionStatus()

Returns the current notification permission status.

getPermissionStatus(): NotificationPermission

Returns: 'granted', 'denied', or 'default'

Note: getPermissionStatus() mirrors the browser's current Notification.permission value. The SDK also uses an internal 'rejected' state for retry / custom prompt flows, but that state is not returned by this method.

Example:

const status = OcmPush.getPermissionStatus();

if (status === 'granted') {
console.log('Already subscribed');
} else if (status === 'denied') {
console.log('User blocked notifications');
} else {
console.log('Permission not yet requested');
OcmPush.showSlidedown();
OcmPush.run();
}

on() / off()

Subscribe to or unsubscribe from SDK events.

on(event: OcmPushEventType, callback: Function): OcmPushAPI
off(event: OcmPushEventType, callback: Function): OcmPushAPI

Returns: The OcmPush instance for chaining.

Example:

function handlePermissionChange(permission) {
console.log('Permission changed:', permission);
}

OcmPush.on('onPermissionChange', handlePermissionChange);

// Later, to unsubscribe:
OcmPush.off('onPermissionChange', handlePermissionChange);

Events

EventPayloadDescription
onPermissionChange'granted' | 'denied' | 'default' | 'rejected'Fired when the permission flow state changes, including custom prompt rejections
onSubscriptionChangeSubscriptionData | nullFired when subscription status changes
onSwVersionReceivedstringFired when the service worker reports its version in debug mode

Example:

OcmPush.on('onPermissionChange', (permission) => {
if (permission === 'granted') {
console.log('User granted permission!');
} else if (permission === 'denied') {
console.log('User denied permission');
} else if (permission === 'rejected') {
console.log('User dismissed the custom prompt or install guide');
}
});

OcmPush.on('onSubscriptionChange', (data) => {
if (data) {
console.log('Subscribed with userId:', data.userId);
// Send userId to your backend for targeting
}
});

Examples

Basic Slidedown

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
OcmPush.showSlidedown();
OcmPush.run();
});
</script>

Multiple Prompts (Bell + Slidedown)

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
OcmPush.showBell();
OcmPush.showSlidedown();
OcmPush.run();
});
</script>

Conditional Prompt Based on Permission Status

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
const status = OcmPush.getPermissionStatus();

if (status === 'default') {
// User hasn't been asked yet
OcmPush.showSlidedown();
OcmPush.run();
} else if (status === 'granted') {
// Already subscribed, just run to update subscription
OcmPush.run();
}
// If 'denied', don't show anything
});
</script>

Trigger Prompt on Button Click

<button id="subscribe-btn">Subscribe to Notifications</button>

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
document.getElementById('subscribe-btn').addEventListener('click', function() {
OcmPush.resetPrompts()
.showSlidedown();

OcmPush.run();
});
});
</script>

Custom Styled Prompts

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
OcmPush.setPromptConfig('slidedown', {
action_message: 'Never miss an update! Subscribe to push notifications.',
accept_button_text: 'Subscribe',
deny_button_text: 'Maybe Later',
accept_button_color: '#28a745',
deny_button_color: '#6c757d',
icon_url: 'https://example.com/icon.png',
});

OcmPush.showSlidedown();
OcmPush.run();
});
</script>

Inline Prompt in Custom Container

<div id="notification-prompt"></div>

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
OcmPush.setPromptConfig('inline', {
selector: '#notification-prompt',
action_message: 'Stay informed with push notifications',
});

OcmPush.showInline();
OcmPush.run();
});
</script>

Category Subscription

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(function(OcmPush) {
OcmPush.setCategories([
{ id: 1, name: 'Product Updates', tag_key: 'products', default_checked: true },
{ id: 2, name: 'Weekly Newsletter', tag_key: 'newsletter', default_checked: true },
{ id: 3, name: 'Promotions & Deals', tag_key: 'promos', default_checked: false },
]);

OcmPush.showCategorySlidedown();
OcmPush.run();
});
</script>

With Event Listeners

<script src="https://your-server.com/sdk/{APP_IDENTIFIER}.js" defer data-manual></script>
<script>
window.OcmPushInit = window.OcmPushInit || [];
window.OcmPushInit.push(async function(OcmPush) {
// Listen for events
OcmPush.on('onPermissionChange', function(permission) {
console.log('Permission:', permission);

if (permission === 'granted') {
// Track conversion in analytics
analytics.track('push_permission_granted');
}
});

OcmPush.on('onSubscriptionChange', function(subscription) {
if (subscription) {
// Send user ID to your backend
fetch('/api/save-push-user', {
method: 'POST',
body: JSON.stringify({ userId: subscription.userId }),
});
}
});

OcmPush.showSlidedown();
await OcmPush.run();
});
</script>

Prompt Types

TypeDescriptionPosition Options
slidedownA banner that slides in from the edge of the pageAll 5 positions (default: top-right)
bellA floating bell widget button (persistent)All 5 positions (default: bottom-right)
category_slidedownA slidedown with category checkboxesAll 5 positions (default: top-right)
inlineRenders inside a specified DOM elementN/A (uses CSS selector)
nativeBrowser's native permission dialogN/A

Configuration Options

Common Options (all prompt types)

OptionTypeDescription
enabledbooleanWhether the prompt is enabled
action_messagestringMain message text
accept_button_textstringText for the accept/allow button
deny_button_textstringText for the deny/cancel button
accept_button_colorstringCSS color for accept button
deny_button_colorstringCSS color for deny button
icon_urlstringURL to an icon image

Slidedown & Category Slidedown Options

OptionTypeDefaultDescription
position'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-right''top-right'Position of the slidedown prompt on the page

Bell-specific Options

OptionTypeDefaultDescription
position'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-right''bottom-right'Position of the bell widget
size'small' | 'medium' | 'large''medium'Size of the bell widget

Inline-specific Options

OptionTypeDescription
selectorstringCSS selector for the container element (required)

Flow Diagram

Manual Mode Flow:

1. Add data-manual to script tag
2. SDK loads and exposes OcmPush API
3. Your code runs via OcmPushInit callback
4. Call show methods to queue prompts (showSlidedown, showBell, etc.)
5. Call run() to:
- Display all queued prompts
- Wait for user interaction
- Request browser permission
- Complete subscription
6. Events fire (onPermissionChange, onSubscriptionChange)
7. run() resolves with subscription data or null

Notes

  • Always call run() after setting up prompts in manual mode
  • The first call to a show method (showSlidedown, showBell, etc.) clears any existing prompts from the global config
  • Subsequent show method calls add to the prompts queue
  • Use resetPrompts() if you need to explicitly clear the queue
  • Bell and inline prompts are "persistent" and can show alongside other prompts
  • Only one "primary" prompt (slidedown, category_slidedown, native) shows at a time
  • Configuration set via setPromptConfig() is merged with global config from the server
  • getSubscription() only reflects state observed during the current page lifecycle
  • onSwVersionReceived is only emitted when debug mode wiring is active