Push notifications
Push notifications integration guide
Send notifications to iOS, Android and browsers with Hibira Push. The API is Beams-compatible: the official Beams server SDKs work once they point at your endpoint, and our client SDKs are forks of the Beams ones with the host made configurable.
Sign in to see these snippets with your own endpoint, and the app page fills in your instance ID. Sign in
How it works
- Turn on push notifications on an app’s page in the portal. You get an instance ID, a secret key and an endpoint.
- Each device or browser registers with a client SDK and subscribes to interests, topics such as news or order-1024. Your server publishes to interests, or to user IDs once a device is linked to a signed-in user.
- The instance ID and endpoint go into your apps. The secret key can publish to every device: keep it on your server, in the HIBIRA_PUSH_SECRET_KEY environment variable, and never in an app or a repository.
- Push is included in every plan. The plan sets how many devices and browsers can register and how fast you can publish.
1. Upload your credentials
- Apple (APNs)
- In Apple Developer, open Certificates, Identifiers & Profiles › Keys, create a key with Apple Push Notifications service (APNs) and download the .p8 file. On the app page, under Push notifications › Apple (APNs), enter the Key ID, your Team ID and the app’s bundle ID, pick the environment and upload the .p8 file. Choose Development (sandbox) for builds run from Xcode, and Production for TestFlight and App Store builds.
- Android (FCM)
- In the Firebase console, open Project settings › Service accounts and click Generate new private key. Upload the JSON file under Push notifications › Android (FCM), and add the same project’s google-services.json to your Android app.
- Web Push
- Nothing to upload: the VAPID keys are created when you turn on push. Your site has to be served over HTTPS (localhost works while developing).
Keys and service accounts are stored encrypted and are never shown again.
2. Register devices and browsers
Client SDK
Chrome, Edge, Firefox, Opera and Safari 16.4+ with standard Web Push and a service worker. @hibira-io/push-web ↗
Install
npm install @hibira-io/push-webAdd the service worker
// public/service-worker.js, served at https://your-site/service-worker.js importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js'); self.HibiraPush.endpoint = 'https://ws.hibira.io';Register the browser
import { Client } from '@hibira-io/push-web'; const push = new Client({ instanceId: 'YOUR_INSTANCE_ID', endpoint: 'https://ws.hibira.io', }); // Browsers only show the permission prompt after a click or tap. document.querySelector('#enable-notifications').addEventListener('click', async () => { await push.start(); await push.addDeviceInterest('hello'); });Link the signed-in user
import { TokenProvider } from '@hibira-io/push-web'; // After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide). await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' })); // On sign-out, so the next person on this browser doesn't get their notifications. await push.stop();
Agent prompt for Web
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Web project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the Hibira client SDK (here: @hibira-io/push-web, https://github.com/hibira-io/hibira-push-web).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- No secret key: it belongs on the server, never in this app
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Install @hibira-io/push-web (it replaces @pusher/push-notifications-web; the API is the same apart from the import and the endpoint option).
3. Serve service-worker.js from the site root (for example public/service-worker.js in Vite, Next.js or Create React App) with the importScripts line and the endpoint from the reference.
4. Create one shared push client module and call start() from a user action such as an "Enable notifications" button, never on page load: browsers block permission prompts that are not triggered by a click.
5. If the app has signed-in users, call setUserId with a TokenProvider pointing at the backend token endpoint after sign-in, and stop() on sign-out.
6. Web Push needs HTTPS (localhost is fine for development); on iPhone and iPad it works only once the site is added to the Home Screen.
7. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent).
8. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
9. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
10. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
11. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
npm install @hibira-io/push-web
```
Add the service worker:
```js
// public/service-worker.js, served at https://your-site/service-worker.js
importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js');
self.HibiraPush.endpoint = 'https://ws.hibira.io';
```
Register the browser:
```js
import { Client } from '@hibira-io/push-web';
const push = new Client({
instanceId: 'YOUR_INSTANCE_ID',
endpoint: 'https://ws.hibira.io',
});
// Browsers only show the permission prompt after a click or tap.
document.querySelector('#enable-notifications').addEventListener('click', async () => {
await push.start();
await push.addDeviceInterest('hello');
});
```
Link the signed-in user:
```js
import { TokenProvider } from '@hibira-io/push-web';
// After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide).
await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' }));
// On sign-out, so the next person on this browser doesn't get their notifications.
await push.stop();
```
Android 7.0+ apps in Kotlin or Java, delivered through Firebase Cloud Messaging. hibira-push-android ↗
Add the Gradle dependencies
// settings.gradle.kts dependencyResolutionManagement { repositories { google() mavenCentral() maven("https://jitpack.io") } } // app/build.gradle.kts (google-services.json from Firebase goes in app/) plugins { id("com.android.application") id("com.google.gms.google-services") } dependencies { implementation("com.google.firebase:firebase-messaging:23.4.0") implementation("com.github.hibira-io:hibira-push-android:1.0.0") }Start the SDK
import android.app.Application import io.hibira.push.PushNotifications class App : Application() { override fun onCreate() { super.onCreate() PushNotifications.setEndpoint(this, "https://ws.hibira.io") PushNotifications.start(this, "YOUR_INSTANCE_ID") PushNotifications.addDeviceInterest("hello") } }Ask for notification permission
// AndroidManifest.xml: <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> // Android 13+ shows nothing until the user allows notifications. if (Build.VERSION.SDK_INT >= 33) { requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1) }Link the signed-in user
import io.hibira.push.PushCallback import io.hibira.push.PushCallbackError import io.hibira.push.auth.AuthData import io.hibira.push.auth.AuthDataGetter import io.hibira.push.auth.PushTokenProvider val tokenProvider = PushTokenProvider( "https://api.your-app.example/push/user-token", object : AuthDataGetter { override fun getAuthData() = AuthData( headers = hashMapOf("Authorization" to "Bearer $sessionToken"), ) }, ) PushNotifications.setUserId(userId, tokenProvider, object : PushCallback<Void, PushCallbackError> { override fun onSuccess(vararg values: Void) {} override fun onFailure(error: PushCallbackError) { Log.w("push", error.message) } }) // On sign-out: PushNotifications.stop()
Agent prompt for Android
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Android project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the Hibira client SDK (here: hibira-push-android, https://github.com/hibira-io/hibira-push-android).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- No secret key: it belongs on the server, never in this app
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Add the JitPack repository and com.github.hibira-io:hibira-push-android (package io.hibira.push; it replaces com.pusher:push-notifications-android). The app needs the Google services Gradle plugin and its google-services.json from the same Firebase project whose service account is uploaded in the portal.
3. Call PushNotifications.setEndpoint and then PushNotifications.start in the Application class (create one and register it in AndroidManifest.xml if the app has none); keep the instance ID and endpoint in BuildConfig fields or resources.
4. On Android 13 and later, declare POST_NOTIFICATIONS in the manifest and request it at a sensible moment (for example after the user turns notifications on), using the project's existing permission approach.
5. If the app has signed-in users, call setUserId with a PushTokenProvider pointing at the backend token endpoint (sending the session credentials) after sign-in, and PushNotifications.stop() on sign-out.
6. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent).
7. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
8. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
9. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
10. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Add the Gradle dependencies:
```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
// app/build.gradle.kts (google-services.json from Firebase goes in app/)
plugins {
id("com.android.application")
id("com.google.gms.google-services")
}
dependencies {
implementation("com.google.firebase:firebase-messaging:23.4.0")
implementation("com.github.hibira-io:hibira-push-android:1.0.0")
}
```
Start the SDK:
```kotlin
import android.app.Application
import io.hibira.push.PushNotifications
class App : Application() {
override fun onCreate() {
super.onCreate()
PushNotifications.setEndpoint(this, "https://ws.hibira.io")
PushNotifications.start(this, "YOUR_INSTANCE_ID")
PushNotifications.addDeviceInterest("hello")
}
}
```
Ask for notification permission:
```kotlin
// AndroidManifest.xml: <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
// Android 13+ shows nothing until the user allows notifications.
if (Build.VERSION.SDK_INT >= 33) {
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
}
```
Link the signed-in user:
```kotlin
import io.hibira.push.PushCallback
import io.hibira.push.PushCallbackError
import io.hibira.push.auth.AuthData
import io.hibira.push.auth.AuthDataGetter
import io.hibira.push.auth.PushTokenProvider
val tokenProvider = PushTokenProvider(
"https://api.your-app.example/push/user-token",
object : AuthDataGetter {
override fun getAuthData() = AuthData(
headers = hashMapOf("Authorization" to "Bearer $sessionToken"),
)
},
)
PushNotifications.setUserId(userId, tokenProvider, object : PushCallback<Void, PushCallbackError> {
override fun onSuccess(vararg values: Void) {}
override fun onFailure(error: PushCallbackError) { Log.w("push", error.message) }
})
// On sign-out:
PushNotifications.stop()
```
Swift apps on iOS 15+ and macOS 12+, delivered through APNs. HibiraPush ↗
Install
// Xcode: File › Add Package Dependencies › https://github.com/hibira-io/hibira-push-ios // or in Package.swift: .package(url: "https://github.com/hibira-io/hibira-push-ios", from: "1.0.0") // Then turn on Signing & Capabilities › Push Notifications for the app target.Register for notifications
import HibiraPush import UIKit final class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { PushNotifications.shared.setEndpoint("https://ws.hibira.io") PushNotifications.shared.start(instanceId: "YOUR_INSTANCE_ID") PushNotifications.shared.registerForRemoteNotifications() try? PushNotifications.shared.addDeviceInterest(interest: "hello") return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { PushNotifications.shared.registerDeviceToken(deviceToken) } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { PushNotifications.shared.handleNotification(userInfo: userInfo) completionHandler(.noData) } }Link the signed-in user
let tokenProvider = PushTokenProvider(authURL: "https://api.your-app.example/push/user-token") { AuthData(headers: ["Authorization": "Bearer \(sessionToken)"], queryParams: [:]) } PushNotifications.shared.setUserId(userId, tokenProvider: tokenProvider) { error in if let error = error { print("push:", error) } } // On sign-out: PushNotifications.shared.stop { }
Agent prompt for iOS / macOS
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this iOS / macOS project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the Hibira client SDK (here: HibiraPush, https://github.com/hibira-io/hibira-push-ios).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- No secret key: it belongs on the server, never in this app
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Add the Swift package https://github.com/hibira-io/hibira-push-ios (product HibiraPush; it replaces pusher/push-notifications-swift and PushNotifications keeps its name) and turn on the Push Notifications capability for the app target.
3. In a SwiftUI app, add a UIApplicationDelegateAdaptor for the AppDelegate in the reference; keep the instance ID and endpoint in an xcconfig or Info.plist entry (the HibiraPushEndpoint Info.plist key also sets the endpoint).
4. Call setEndpoint before start, forward the device token from didRegisterForRemoteNotificationsWithDeviceToken, and pass received notifications to handleNotification.
5. If the app has signed-in users, call setUserId with a PushTokenProvider pointing at the backend token endpoint (sending the session credentials) after sign-in, and stop on sign-out.
6. Remind me that the APNs environment chosen in the portal must match the build: Development (sandbox) for Xcode builds, Production for TestFlight and the App Store.
7. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent).
8. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
9. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
10. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
11. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```swift
// Xcode: File › Add Package Dependencies › https://github.com/hibira-io/hibira-push-ios
// or in Package.swift:
.package(url: "https://github.com/hibira-io/hibira-push-ios", from: "1.0.0")
// Then turn on Signing & Capabilities › Push Notifications for the app target.
```
Register for notifications:
```swift
import HibiraPush
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
PushNotifications.shared.setEndpoint("https://ws.hibira.io")
PushNotifications.shared.start(instanceId: "YOUR_INSTANCE_ID")
PushNotifications.shared.registerForRemoteNotifications()
try? PushNotifications.shared.addDeviceInterest(interest: "hello")
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
PushNotifications.shared.registerDeviceToken(deviceToken)
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
PushNotifications.shared.handleNotification(userInfo: userInfo)
completionHandler(.noData)
}
}
```
Link the signed-in user:
```swift
let tokenProvider = PushTokenProvider(authURL: "https://api.your-app.example/push/user-token") {
AuthData(headers: ["Authorization": "Bearer \(sessionToken)"], queryParams: [:])
}
PushNotifications.shared.setUserId(userId, tokenProvider: tokenProvider) { error in
if let error = error { print("push:", error) }
}
// On sign-out:
PushNotifications.shared.stop { }
```
3. Publish from your server
Server SDK
Publish from Node.js with the official Beams server SDK, pointed at your endpoint. @pusher/push-notifications-server ↗
Install
npm install @pusher/push-notifications-serverPublish to an interest
const PushNotifications = require('@pusher/push-notifications-server'); const beams = new PushNotifications({ instanceId: 'YOUR_INSTANCE_ID', secretKey: process.env.HIBIRA_PUSH_SECRET_KEY, endpoint: 'ws.hibira.io', }); beams.protocol = 'https'; // the SDK switches to http when an endpoint is set await beams.publishToInterests(['hello'], { apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } }, fcm: { notification: { title: 'Hello', body: 'Hello, world!' } }, web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } }, });Add the user token endpoint
// Express: the client SDKs call GET /push/user-token?user_id=... app.get('/push/user-token', requireLogin, (req, res) => { if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401); res.json(beams.generateToken(String(req.user.id))); // { token: '...' } });Publish to a signed-in user
await beams.publishToUsers(['user-1'], { apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } }, fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } }, web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } }, });
Agent prompt for Node.js
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Node.js project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: @pusher/push-notifications-server, https://github.com/pusher/push-notifications-node).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Create one shared module that builds the PushNotifications client from environment variables, with the endpoint option and beams.protocol set as in the reference (without them the SDK talks to pusher.com, or to the endpoint over plain http).
3. If the app has signed-in users, add the token route behind the project's existing authentication middleware; it must refuse a user_id that is not the signed-in user's.
4. Publish from the places that should notify (jobs, controllers, event handlers) through the shared module, and log the publish ID it returns.
5. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
6. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
7. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
8. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
9. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
npm install @pusher/push-notifications-server
```
Publish to an interest:
```js
const PushNotifications = require('@pusher/push-notifications-server');
const beams = new PushNotifications({
instanceId: 'YOUR_INSTANCE_ID',
secretKey: process.env.HIBIRA_PUSH_SECRET_KEY,
endpoint: 'ws.hibira.io',
});
beams.protocol = 'https'; // the SDK switches to http when an endpoint is set
await beams.publishToInterests(['hello'], {
apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } },
fcm: { notification: { title: 'Hello', body: 'Hello, world!' } },
web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } },
});
```
Add the user token endpoint:
```js
// Express: the client SDKs call GET /push/user-token?user_id=...
app.get('/push/user-token', requireLogin, (req, res) => {
if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401);
res.json(beams.generateToken(String(req.user.id))); // { token: '...' }
});
```
Publish to a signed-in user:
```js
await beams.publishToUsers(['user-1'], {
apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } },
fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
});
```
Publish from any PHP app with the official Beams server SDK, pointed at your endpoint. pusher/pusher-push-notifications ↗
Install
composer require pusher/pusher-push-notificationsPublish to an interest
use Pusher\PushNotifications\PushNotifications; $beams = new PushNotifications([ 'instanceId' => 'YOUR_INSTANCE_ID', 'secretKey' => getenv('HIBIRA_PUSH_SECRET_KEY'), 'endpoint' => 'https://ws.hibira.io', ]); $beams->publishToInterests(['hello'], [ 'apns' => ['aps' => ['alert' => ['title' => 'Hello', 'body' => 'Hello, world!']]], 'fcm' => ['notification' => ['title' => 'Hello', 'body' => 'Hello, world!']], 'web' => ['notification' => ['title' => 'Hello', 'body' => 'Hello, world!']], ]);Add the user token endpoint
// GET /push/user-token?user_id=..., for a signed-in user only $userId = (string) $currentUser->id; if (($_GET['user_id'] ?? '') !== $userId) { http_response_code(401); exit; } header('Content-Type: application/json'); echo json_encode($beams->generateToken($userId)); // {"token": "..."}Publish to a signed-in user
$beams->publishToUsers(['user-1'], [ 'apns' => ['aps' => ['alert' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']]], 'fcm' => ['notification' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']], 'web' => ['notification' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']], ]);
Agent prompt for PHP
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this PHP project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: pusher/pusher-push-notifications, https://github.com/pusher/push-notifications-php).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Create one small factory or service that builds PushNotifications from environment variables, always with the endpoint option (without it the SDK talks to pusher.com), and use it wherever the app publishes.
3. If the app has signed-in users, add the token endpoint behind the project's existing session check; it must refuse a user_id that is not the signed-in user's.
4. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
5. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
6. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
7. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
8. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
composer require pusher/pusher-push-notifications
```
Publish to an interest:
```php
use Pusher\PushNotifications\PushNotifications;
$beams = new PushNotifications([
'instanceId' => 'YOUR_INSTANCE_ID',
'secretKey' => getenv('HIBIRA_PUSH_SECRET_KEY'),
'endpoint' => 'https://ws.hibira.io',
]);
$beams->publishToInterests(['hello'], [
'apns' => ['aps' => ['alert' => ['title' => 'Hello', 'body' => 'Hello, world!']]],
'fcm' => ['notification' => ['title' => 'Hello', 'body' => 'Hello, world!']],
'web' => ['notification' => ['title' => 'Hello', 'body' => 'Hello, world!']],
]);
```
Add the user token endpoint:
```php
// GET /push/user-token?user_id=..., for a signed-in user only
$userId = (string) $currentUser->id;
if (($_GET['user_id'] ?? '') !== $userId) {
http_response_code(401);
exit;
}
header('Content-Type: application/json');
echo json_encode($beams->generateToken($userId)); // {"token": "..."}
```
Publish to a signed-in user:
```php
$beams->publishToUsers(['user-1'], [
'apns' => ['aps' => ['alert' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']]],
'fcm' => ['notification' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']],
'web' => ['notification' => ['title' => 'Order shipped', 'body' => 'Order #1024 is on its way.']],
]);
```
Laravel apps: a container binding with your endpoint, a token route and publishing from jobs. pusher/pusher-push-notifications ↗
Install
composer require pusher/pusher-push-notificationsSet your push credentials
HIBIRA_PUSH_INSTANCE_ID=YOUR_INSTANCE_ID HIBIRA_PUSH_SECRET_KEY= HIBIRA_PUSH_ENDPOINT=https://ws.hibira.ioBind the client
// config/services.php 'hibira_push' => [ 'instance_id' => env('HIBIRA_PUSH_INSTANCE_ID'), 'secret_key' => env('HIBIRA_PUSH_SECRET_KEY'), 'endpoint' => env('HIBIRA_PUSH_ENDPOINT'), ], // app/Providers/AppServiceProvider.php, in register() $this->app->singleton(\Pusher\PushNotifications\PushNotifications::class, fn () => new \Pusher\PushNotifications\PushNotifications([ 'instanceId' => config('services.hibira_push.instance_id'), 'secretKey' => config('services.hibira_push.secret_key'), 'endpoint' => config('services.hibira_push.endpoint'), ]));Add the user token endpoint
// routes/web.php (or routes/api.php with your API guard) use Illuminate\Http\Request; use Pusher\PushNotifications\PushNotifications; Route::middleware('auth')->get('/push/user-token', function (Request $request, PushNotifications $beams) { $userId = (string) $request->user()->id; abort_unless($request->query('user_id') === $userId, 401); return $beams->generateToken($userId); // {"token": "..."} });Publish to a signed-in user
app(\Pusher\PushNotifications\PushNotifications::class)->publishToUsers([(string) $order->user_id], [ 'apns' => ['aps' => ['alert' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]]], 'fcm' => ['notification' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]], 'web' => ['notification' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]], ]);
Agent prompt for Laravel
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Laravel project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: pusher/pusher-push-notifications, https://github.com/pusher/push-notifications-php).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Add the HIBIRA_PUSH_* entries to .env and .env.example, the hibira_push block to config/services.php, and the singleton binding in AppServiceProvider::register, always passing the endpoint (without it the SDK talks to pusher.com).
3. If the project uses laravel-notification-channels/pusher-push-notifications, also bind PushNotifications for its PusherChannel with the same options, because the package builds its own client without an endpoint.
4. Add the token route behind the project's existing auth middleware (web session or API guard, whichever the mobile and web clients use); it must refuse a user_id that is not the signed-in user's.
5. Publish from queued jobs or notifications rather than inside the request where possible.
6. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
7. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
8. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
9. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
10. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
composer require pusher/pusher-push-notifications
```
Set your push credentials:
```ini
HIBIRA_PUSH_INSTANCE_ID=YOUR_INSTANCE_ID
HIBIRA_PUSH_SECRET_KEY=
HIBIRA_PUSH_ENDPOINT=https://ws.hibira.io
```
Bind the client:
```php
// config/services.php
'hibira_push' => [
'instance_id' => env('HIBIRA_PUSH_INSTANCE_ID'),
'secret_key' => env('HIBIRA_PUSH_SECRET_KEY'),
'endpoint' => env('HIBIRA_PUSH_ENDPOINT'),
],
// app/Providers/AppServiceProvider.php, in register()
$this->app->singleton(\Pusher\PushNotifications\PushNotifications::class, fn () => new \Pusher\PushNotifications\PushNotifications([
'instanceId' => config('services.hibira_push.instance_id'),
'secretKey' => config('services.hibira_push.secret_key'),
'endpoint' => config('services.hibira_push.endpoint'),
]));
```
Add the user token endpoint:
```php
// routes/web.php (or routes/api.php with your API guard)
use Illuminate\Http\Request;
use Pusher\PushNotifications\PushNotifications;
Route::middleware('auth')->get('/push/user-token', function (Request $request, PushNotifications $beams) {
$userId = (string) $request->user()->id;
abort_unless($request->query('user_id') === $userId, 401);
return $beams->generateToken($userId); // {"token": "..."}
});
```
Publish to a signed-in user:
```php
app(\Pusher\PushNotifications\PushNotifications::class)->publishToUsers([(string) $order->user_id], [
'apns' => ['aps' => ['alert' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]]],
'fcm' => ['notification' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]],
'web' => ['notification' => ['title' => 'Order shipped', 'body' => "Order #{$order->id} is on its way."]],
]);
```
Publish from Django, Flask, FastAPI or scripts with the official Beams server SDK. pusher_push_notifications ↗
Install
pip install pusher_push_notificationsPublish to an interest
import os from pusher_push_notifications import PushNotifications beams = PushNotifications( instance_id='YOUR_INSTANCE_ID', secret_key=os.environ['HIBIRA_PUSH_SECRET_KEY'], endpoint='ws.hibira.io', # host only; the SDK always uses https ) beams.publish_to_interests( interests=['hello'], publish_body={ 'apns': {'aps': {'alert': {'title': 'Hello', 'body': 'Hello, world!'}}}, 'fcm': {'notification': {'title': 'Hello', 'body': 'Hello, world!'}}, 'web': {'notification': {'title': 'Hello', 'body': 'Hello, world!'}}, }, )Add the user token endpoint
# Flask: GET /push/user-token?user_id=..., for a signed-in user only def push_user_token(): user_id = str(current_user.id) if request.args.get('user_id') != user_id: abort(401) return beams.generate_token(user_id) # {'token': '...'}Publish to a signed-in user
beams.publish_to_users( user_ids=['user-1'], publish_body={ 'apns': {'aps': {'alert': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}}}, 'fcm': {'notification': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}}, 'web': {'notification': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}}, }, )
Agent prompt for Python
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Python project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: pusher_push_notifications, https://github.com/pusher/push-notifications-python).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Create one module that builds PushNotifications from environment variables (or the framework's settings), always with endpoint set to the host from the reference (without it the SDK talks to pusher.com).
3. If the app has signed-in users, add the token view or route in the project's framework behind its existing login check; it must refuse a user_id that is not the signed-in user's.
4. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
5. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
6. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
7. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
8. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
pip install pusher_push_notifications
```
Publish to an interest:
```python
import os
from pusher_push_notifications import PushNotifications
beams = PushNotifications(
instance_id='YOUR_INSTANCE_ID',
secret_key=os.environ['HIBIRA_PUSH_SECRET_KEY'],
endpoint='ws.hibira.io', # host only; the SDK always uses https
)
beams.publish_to_interests(
interests=['hello'],
publish_body={
'apns': {'aps': {'alert': {'title': 'Hello', 'body': 'Hello, world!'}}},
'fcm': {'notification': {'title': 'Hello', 'body': 'Hello, world!'}},
'web': {'notification': {'title': 'Hello', 'body': 'Hello, world!'}},
},
)
```
Add the user token endpoint:
```python
# Flask: GET /push/user-token?user_id=..., for a signed-in user only
def push_user_token():
user_id = str(current_user.id)
if request.args.get('user_id') != user_id:
abort(401)
return beams.generate_token(user_id) # {'token': '...'}
```
Publish to a signed-in user:
```python
beams.publish_to_users(
user_ids=['user-1'],
publish_body={
'apns': {'aps': {'alert': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}}},
'fcm': {'notification': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}},
'web': {'notification': {'title': 'Order shipped', 'body': 'Order #1024 is on its way.'}},
},
)
```
Publish from Go services with the official Beams server SDK and a custom base URL. push-notifications-go ↗
Install
go get github.com/pusher/push-notifications-goPublish to an interest
import ( "os" pushnotifications "github.com/pusher/push-notifications-go" ) beams, err := pushnotifications.New("YOUR_INSTANCE_ID", os.Getenv("HIBIRA_PUSH_SECRET_KEY"), pushnotifications.WithCustomBaseURL("https://ws.hibira.io")) if err != nil { return err } publishID, err := beams.PublishToInterests([]string{"hello"}, map[string]interface{}{ "apns": map[string]interface{}{"aps": map[string]interface{}{ "alert": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}}}, "fcm": map[string]interface{}{ "notification": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}}, "web": map[string]interface{}{ "notification": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}}, })Add the user token endpoint
// GET /push/user-token?user_id=..., behind your session middleware http.HandleFunc("/push/user-token", func(w http.ResponseWriter, r *http.Request) { userID := currentUserID(r) if userID == "" || r.URL.Query().Get("user_id") != userID { http.Error(w, "unauthorized", http.StatusUnauthorized) return } token, err := beams.GenerateToken(userID) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(token) // {"token": "..."} })Publish to a signed-in user
publishID, err := beams.PublishToUsers([]string{"user-1"}, map[string]interface{}{ "fcm": map[string]interface{}{ "notification": map[string]interface{}{"title": "Order shipped", "body": "Order #1024 is on its way."}}, "apns": map[string]interface{}{"aps": map[string]interface{}{ "alert": map[string]interface{}{"title": "Order shipped", "body": "Order #1024 is on its way."}}}, })
Agent prompt for Go
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this Go project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: push-notifications-go, https://github.com/pusher/push-notifications-go).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Build one pushnotifications client at startup from environment variables, always with pushnotifications.WithCustomBaseURL (without it the SDK talks to pusher.com), and pass it to the code that publishes.
3. If the service has signed-in users, add the token handler behind the existing session or auth middleware; it must refuse a user_id that is not the signed-in user's.
4. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
5. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
6. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
7. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
8. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Install:
```shell
go get github.com/pusher/push-notifications-go
```
Publish to an interest:
```go
import (
"os"
pushnotifications "github.com/pusher/push-notifications-go"
)
beams, err := pushnotifications.New("YOUR_INSTANCE_ID", os.Getenv("HIBIRA_PUSH_SECRET_KEY"),
pushnotifications.WithCustomBaseURL("https://ws.hibira.io"))
if err != nil {
return err
}
publishID, err := beams.PublishToInterests([]string{"hello"}, map[string]interface{}{
"apns": map[string]interface{}{"aps": map[string]interface{}{
"alert": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}}},
"fcm": map[string]interface{}{
"notification": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}},
"web": map[string]interface{}{
"notification": map[string]interface{}{"title": "Hello", "body": "Hello, world!"}},
})
```
Add the user token endpoint:
```go
// GET /push/user-token?user_id=..., behind your session middleware
http.HandleFunc("/push/user-token", func(w http.ResponseWriter, r *http.Request) {
userID := currentUserID(r)
if userID == "" || r.URL.Query().Get("user_id") != userID {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
token, err := beams.GenerateToken(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(token) // {"token": "..."}
})
```
Publish to a signed-in user:
```go
publishID, err := beams.PublishToUsers([]string{"user-1"}, map[string]interface{}{
"fcm": map[string]interface{}{
"notification": map[string]interface{}{"title": "Order shipped", "body": "Order #1024 is on its way."}},
"apns": map[string]interface{}{"aps": map[string]interface{}{
"alert": map[string]interface{}{"title": "Order shipped", "body": "Order #1024 is on its way."}}},
})
```
Any language or a quick test from the terminal: the publish API is plain HTTPS and JSON. REST API ↗
Publish to an interest
curl -X POST "https://ws.hibira.io/publish_api/v1/instances/YOUR_INSTANCE_ID/publishes/interests" \ -H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "interests": ["hello"], "apns": {"aps": {"alert": {"title": "Hello", "body": "Hello, world!"}}}, "fcm": {"notification": {"title": "Hello", "body": "Hello, world!"}}, "web": {"notification": {"title": "Hello", "body": "Hello, world!"}} }' # {"publishId":"pubid-..."}Publish to a signed-in user
curl -X POST "https://ws.hibira.io/publish_api/v1/instances/YOUR_INSTANCE_ID/publishes/users" \ -H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"users": ["user-1"], "fcm": {"notification": {"title": "Order shipped", "body": "Order #1024 is on its way."}}}'Delete a user
# Unlinks every device of the user, for example when their account is deleted. curl -X DELETE "https://ws.hibira.io/customer_api/v1/instances/YOUR_INSTANCE_ID/users/user-1" \ -H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY"
Agent prompt for curl / HTTP
Paste this into Claude Code, Cursor, GitHub Copilot or another AI coding agent. It carries the instance ID and endpoint; the secret key stays an environment variable.
Add Hibira push notifications to this curl / HTTP project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: REST API, https://hibira.io/guides/push-notifications).
Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)
What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Use the HTTP client the project already has; send JSON with Authorization: Bearer and the secret key from the environment.
3. A publish takes up to 100 interests or 1,000 user IDs; split larger audiences across several requests and retry a 429 response after the Retry-After delay.
4. User tokens for the client SDKs are HS256 JWTs signed with the secret key, with sub set to the user ID, iss set to https://<instance ID>.pushnotifications.pusher.com and exp in the future; prefer a maintained JWT library to build them.
5. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
6. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
7. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
8. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
9. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.
Reference setup from the Hibira push notifications guide (adapt it to the project's structure):
Publish to an interest:
```shell
curl -X POST "https://ws.hibira.io/publish_api/v1/instances/YOUR_INSTANCE_ID/publishes/interests" \
-H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"interests": ["hello"],
"apns": {"aps": {"alert": {"title": "Hello", "body": "Hello, world!"}}},
"fcm": {"notification": {"title": "Hello", "body": "Hello, world!"}},
"web": {"notification": {"title": "Hello", "body": "Hello, world!"}}
}'
# {"publishId":"pubid-..."}
```
Publish to a signed-in user:
```shell
curl -X POST "https://ws.hibira.io/publish_api/v1/instances/YOUR_INSTANCE_ID/publishes/users" \
-H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"users": ["user-1"], "fcm": {"notification": {"title": "Order shipped", "body": "Order #1024 is on its way."}}}'
```
Delete a user:
```shell
# Unlinks every device of the user, for example when their account is deleted.
curl -X DELETE "https://ws.hibira.io/customer_api/v1/instances/YOUR_INSTANCE_ID/users/user-1" \
-H "Authorization: Bearer $HIBIRA_PUSH_SECRET_KEY"
```
4. Signed-in users
To reach a person on every device they use, link each device to your own user ID. The client SDK calls your token endpoint with ?user_id=…; the endpoint checks that the request comes from that signed-in user and answers with the token that generateToken makes from your secret key (every Beams server SDK has it). Then publish to the user ID instead of an interest. Deleting a user unlinks all of their devices.
Call stop when the user signs out, so the next person on that device does not get their notifications.
5. Send a test
On the app page, under Push notifications › Send a test, enter an interest (hello in the snippets above), a title and a body, and click Send test. Devices subscribed to that interest get it within seconds, and the Subscribers meter shows how many devices and browsers are registered.
Troubleshooting
- A device or browser never shows up under Subscribers
- Check that the client calls start with this app’s instance ID and endpoint, and that the user allowed notifications. On Android, google-services.json must come from the same Firebase project as the service account you uploaded.
- iPhones and iPads get nothing
- The APNs environment must match the build: Development (sandbox) for builds run from Xcode, Production for TestFlight and the App Store. The bundle ID must match the app exactly, and the app target needs the Push Notifications capability.
- start() fails with “service worker missing”
- Serve /service-worker.js from the root of your site, over HTTPS, with the importScripts line from the Web guide. A service worker in a subfolder only controls that folder.
- Safari on iPhone never asks for permission
- Web Push on iOS and iPadOS 16.4+ works only after the site is added to the Home Screen, and the permission prompt has to come from a tap.
- The server SDK still calls pusher.com, or fails over http
- Set the endpoint option. The Node.js SDK also needs beams.protocol = 'https', and the Go SDK takes WithCustomBaseURL.
- Publishing answers 401
- The server is using the wrong secret key, or one that was rotated longer ago than its grace period. Copy the current key from the app page.
- Publishing answers 429
- You are publishing faster than your plan allows. Wait for the Retry-After delay, and target up to 100 interests or 1,000 users in one publish instead of one request each.
- Registering a device answers 402
- The app has reached its plan’s subscriber limit. Upgrade the plan, or delete users who left so their devices are removed.
- setUserId fails
- Your token endpoint must answer 200 with the JSON that generateToken returns for the user_id it is asked about, using this app’s secret key. A device that is linked to another user must call stop first.
Moving from Pusher Beams? Switch the client SDK packages to ours, set the endpoint in your server SDK, upload your APNs key and FCM service account, and publish to both services until your users have updated. Devices register again on their first start. Migrating from Pusher →