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)
undefinedvalues are skipped (won't overwrite existing values)- Primitives and
nullvalues 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 currentNotification.permissionvalue. 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
| Event | Payload | Description |
|---|---|---|
onPermissionChange | 'granted' | 'denied' | 'default' | 'rejected' | Fired when the permission flow state changes, including custom prompt rejections |
onSubscriptionChange | SubscriptionData | null | Fired when subscription status changes |
onSwVersionReceived | string | Fired 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
| Type | Description | Position Options |
|---|---|---|
slidedown | A banner that slides in from the edge of the page | All 5 positions (default: top-right) |
bell | A floating bell widget button (persistent) | All 5 positions (default: bottom-right) |
category_slidedown | A slidedown with category checkboxes | All 5 positions (default: top-right) |
inline | Renders inside a specified DOM element | N/A (uses CSS selector) |
native | Browser's native permission dialog | N/A |
Configuration Options
Common Options (all prompt types)
| Option | Type | Description |
|---|---|---|
enabled | boolean | Whether the prompt is enabled |
action_message | string | Main message text |
accept_button_text | string | Text for the accept/allow button |
deny_button_text | string | Text for the deny/cancel button |
accept_button_color | string | CSS color for accept button |
deny_button_color | string | CSS color for deny button |
icon_url | string | URL to an icon image |
Slidedown & Category Slidedown Options
| Option | Type | Default | Description |
|---|---|---|---|
position | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-right' | Position of the slidedown prompt on the page |
Bell-specific Options
| Option | Type | Default | Description |
|---|---|---|---|
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
| Option | Type | Description |
|---|---|---|
selector | string | CSS 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 lifecycleonSwVersionReceivedis only emitted when debug mode wiring is active