Migrate from OneSignal
OneSignal lets you export your application's VAPID keys, which makes this the cleanest kind of migration: bring the keys across and every existing subscriber stays subscribed — same browser endpoint, same delivery, no re-prompt. This guide walks the full cutover, from key import to swapping the SDK to verifying the count.
New to the general approach? Read the migration overview first — this guide is the OneSignal-specific version of that playbook.
Why teams switch from OneSignal
- Email is built in. OneSignal is push-first; email means a second tool. ReachBell ships campaign and transactional email on AWS SES against the same segments, on one bill — so you can retire a separate Mailchimp or SendGrid line item.
- Automations without the enterprise gate. Welcome flows, cart recovery, and win-back journeys are included on paid plans, not held behind a sales call.
- INR billing with GST. Pay in rupees via UPI, cards, or net banking and download a GST invoice — no USD card swipe, no FX markup.
1. Import your VAPID keys
In OneSignal, open Settings → Keys & IDs and copy the VAPID public/private pair. Paste them into ReachBell when you create the project, or import them with the API:
curl -X POST https://api.reachbell.com/migration/project/proj_01HX2.../vapid-import \
-H "x-api-key: rb_live_yourkey" \
-H "Content-Type: application/json" \
-d '{
"publicKey": "BNc...",
"privateKey": "tZk..."
}'{
"success": true,
"message": "VAPID keys imported. Existing subscribers registered with these keys will continue working silently."
}Because web-push subscriptions are bound to the VAPID key pair and your origin — not to OneSignal — every existing browser keeps resolving to the same push endpoint the moment those keys are in place. This is why we built import-VAPID first: it carries your whole list with zero churn.
No permission re-prompt. The browser already granted push for your origin, and that grant survives the provider swap. Importing the keys keeps the same subscription alive, so users see no dialog, no banner, nothing.
2. Replace the SDK script
Delete the OneSignalSDK.page.js include and the OneSignalSDKWorker.js service worker from your site root. Drop in ReachBell's loader plus reachbell-sw.js — see the JavaScript integration for the complete walkthrough.
<!-- Remove -->
<script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>
<!-- Add -->
<script src="https://app.reachbell.com/reachbell.js" defer></script>
<script>
window.addEventListener("DOMContentLoaded", () => {
ReachBell.init({ apiKey: "rb_live_yourkey" });
});
</script>The service worker must live at the root of your origin (https://yoursite.com/reachbell-sw.js) so its scope covers every page. You can rename OneSignalSDKWorker.js to reachbell-sw.js, or just drop ours alongside it during the cutover.
3. Import tags and user IDs
The VAPID import keeps subscriptions alive; export the metadata so your segments rebuild. Use OneSignal's REST csv_export endpoint (or Audience → Export in the dashboard) — it returns every subscriber with their external_user_id, tags, language, timezone, and segment memberships.
Bring the rows in via the CSV uploader, or POST them to the import endpoint in batches of up to 10,000:
curl -X POST https://api.reachbell.com/migration/project/proj_01HX2.../subscribers-import \
-H "x-api-key: rb_live_yourkey" \
-H "Content-Type: application/json" \
-d '{
"source": "onesignal",
"subscribers": [
{
"channel": "web_push",
"subscription": {
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"keys": { "p256dh": "BNc...", "auth": "tZk..." }
},
"externalId": "user_4827",
"tags": ["premium", "india"],
"country": "IN",
"browser": "Chrome"
}
]
}'{ "imported": 1, "skipped": 0, "failed": 0, "errors": [] }Every imported subscriber is auto-tagged migrated and migrated_from_onesignal. The import is idempotent — it dedupes on the subscription, so re-running the same file skips existing rows (skipped) rather than duplicating them. Segments rebuild automatically from the tag columns.
4. Verify the count
Open ReachBell → Project → Verification, reload your site, and your browser should appear as an active subscriber within seconds. Confirm the total programmatically:
curl https://api.reachbell.com/migration/project/proj_01HX2.../status \
-H "x-api-key: rb_live_yourkey"{
"totalActive": 47980,
"migrated": 47980,
"bySource": [{ "source": "onesignal", "count": 47980 }]
}Because you imported the VAPID keys, totalActive should match your OneSignal count almost immediately. Send a test push to yourself, confirm it lands, then route traffic.
Run both in parallel during cutover
You can keep OneSignal's service worker registered alongside ReachBell's for a short window. Send a test campaign through ReachBell and confirm delivery and click-through match OneSignal's. Once you're satisfied, remove the OneSignal SDK include and delete OneSignalSDKWorker.js from your root — browsers unregister the old worker on their next visit.
What about templates and automations?
- Templates import by copy-paste — ReachBell uses the same
{{variable}}Handlebars-style syntax. - Automations are rebuilt visually in the journey designer. Every OneSignal node type — wait, branch, send, exit — has a direct equivalent, and the team will do the rebuild for you on every paid plan.
Email sale@reachbell.com with your OneSignal app ID and a sample CSV and they'll handle the import, the segment rebuild, and a verification call. Most OneSignal cutovers take a single afternoon.
What's next?
- Wire up the SDK in full with the JavaScript integration.
- Rebuild your audiences with the Segments guide.
- Recreate your flows in the Automation guide.