Skip to content

Quickstart

In the console, open Hive Push and click New app. Give it a name and pick the region closest to your users. The app page shows its App ID (app_...), Public key (pk_...), Host and, on request, its Secret key (sk_...).

The host is push-<region>.dockhive.io, for example push-global-1.dockhive.io. The public key and host are safe to put in web pages; keep the secret key on your server. It sends notifications and signs user tokens. If it leaks, rotate it in the console: the old key stops working at once, and user tokens signed with it stop working too.

In the app’s settings, add each site that will use Hive Push under Allowed origins, as https://example.com or https://app.example.com:8443 (no path). The browser SDK refuses to work anywhere else. http://localhost on any port is always allowed, so you can develop without adding it.

Browsers deliver notifications to a service worker served from your own site. Save this one line at the root of your site as /hive-push-sw.js, using your app’s host:

importScripts('https://push-global-1.dockhive.io/sdk/v1/hive-push-sw.js');

It shows the notification, opens (or focuses) the notification’s link when it’s clicked, and reports delivered, clicked and dismissed back to Hive Push for your counts. Push messages that are not from Hive Push are left to your own code.

Already have a service worker? Add the same line at the top of it and pass its path as serviceWorker in the next step.

<script src="https://push-global-1.dockhive.io/sdk/v1/push.js"></script>
<button id="notify">Turn on notifications</button>
<script>
const push = HivePush.init({
key: 'pk_your_public_key',
region: 'global-1', // or host: 'push-global-1.dockhive.io'
serviceWorker: '/hive-push-sw.js'
});
document.getElementById('notify').addEventListener('click', async () => {
try {
// your server returns a user token for the signed-in user (step 5)
const { userId, token } = await fetch('/api/hive-push-token').then((r) => r.json());
await push.setUser(userId, token);
await push.subscribe(); // asks permission, then registers this browser
} catch (e) {
console.warn('Notifications not enabled:', e.code, e.message);
}
});
</script>

subscribe() asks for permission, registers the service worker and registers this browser as a device (dev_...). It’s safe to call again: it reuses the same subscription and device.

A user token proves that a browser belongs to one of your signed-in users, so nobody can subscribe as someone else or read their inbox. Your server makes it with the secret key. Return it from an endpoint your page calls, like /api/hive-push-token above:

import crypto from 'node:crypto';
function hivePushUserToken(secretKey, userId, ttlSeconds = 3600) {
const body = Buffer.from(JSON.stringify({ u: userId, exp: Math.floor(Date.now() / 1000) + ttlSeconds })).toString('base64url');
return body + '.' + crypto.createHmac('sha256', secretKey).update(body).digest('hex');
}
// Express example: only for a signed-in user
app.get('/api/hive-push-token', (req, res) => {
const userId = String(req.user.id);
res.json({ userId, token: hivePushUserToken(process.env.HIVE_PUSH_SECRET_KEY, userId) });
});

More in User tokens.

Terminal window
curl https://push-global-1.dockhive.io/v1/apps/app_0123456789abcdef/notifications \
-H "Authorization: Bearer $HIVE_PUSH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"users": ["user-42"]},
"title": "Your order shipped",
"body": "It arrives on Thursday.",
"url": "https://shop.example/orders/77"
}'
{"id": "ntf_5b0c9d2e7f1a3c4b", "targeted": 2, "inbox": 1}

targeted is the number of browsers the notification goes to, and inbox the number of inbox items created. Next: Sending notifications and the in-app inbox.

Load the SDK from your app’s host (/sdk/v1/push.js). It has no dependencies, works in every browser that supports web push, and exposes window.HivePush.

const push = HivePush.init({
key: 'pk_...', // required: the app's public key
region: 'global-1', // or host: 'push-global-1.dockhive.io'
serviceWorker: '/hive-push-sw.js', // default '/hive-push-sw.js'
scope: '/' // optional service worker scope
});
Method Returns What it does
push.subscribe() { deviceId } Asks for permission (if not yet granted), registers the service worker, subscribes to push and registers this browser. Call it from a click or tap.
push.setUser(userId, token) Attaches your signed-in user to this browser and turns on the inbox. Call it before or after subscribe().
push.setUser(null) Logs out: the browser keeps its subscription but no longer belongs to a user.
push.setTags({ plan: 'pro' }) Replaces this browser’s tags (string values, at most 20 keys).
push.unsubscribe() Unsubscribes from push and removes the device.
push.permission() 'granted', 'denied', 'default' or 'unsupported' The current notification permission.
push.supported() boolean Whether this browser supports web push.
push.deviceId() string or null This browser’s device id (kept in localStorage).
push.inbox.list({ before, limit }) { items, unread } The user’s inbox. See In-app inbox.
push.inbox.markRead(ids) Marks one id, an array of ids, or 'all' as read.
push.inbox.onMessage(cb) stop() Calls cb(item) for every new inbox item, live.

Errors are thrown as HivePushError with a code (see Error codes), a message and the HTTP status (0 for network errors). The SDK adds these codes itself: unsupported, permission_denied, invalid_options and network.

Users can block notifications in their browser. When push.permission() is 'denied', only the user can change it, in the browser’s site settings.