The Orbit mobile app
Orbit has a native mobile app for iOS and Android. It keeps the Inbox, your voice history, and your voicemail in your pocket so your team can answer customers without being at a desk. This page covers what’s on each of the mobile app’s five tabs and how to get started. For the mobile SDK-bridging surfaces (React Native SDK, CallKit), see the SDKs reference.Sign in
Sign in with the same work email you use for the web dashboard. If your account belongs to more than one workspace (org), a workspace picker appears; if your account has multi-factor verification enabled, continue your sign-in in a browser instead. The app keeps you signed in between restarts using the OS-level keychain / Keystore.Tabs
The bottom tab bar is the same on iOS and Android. The order is: Softphone, Meet, Inbox, Calls, More.Softphone
The Softphone is a working inbound and outbound caller. Connects, dials, mutes, and hangs up like a real phone. The dial box takes E.164 numbers; the softphone is live in real-time until you sign out.Meet
Meet is the video-room surface — the same meeting rooms you’d create on the dashboard. Anyone you invite via link can join from a browser; the tab lists live and scheduled rooms.Inbox
The Inbox tab shows the same unified inbox your team sees in the web dashboard — customer conversations, the team-chat channels you belong to, and direct messages, all sorted by activity. Each row shows a channel avatar, the conversation title (a contact’s name, a team channel’s name, or the DM counterparty’s resolved presence name), a text preview, an unread-count badge, and a compact relative timestamp. Unread conversations sort the same way they do on the dashboard’s own Inbox page, so what your desktop colleague sees and what you see match. Tap the Inbox tab’s Refresh button (or pull-to-refresh in the future) to re-poll.Calls
The Calls tab shows your call history and voicemail as two segments of one screen — to keep the bottom tab count at five instead of adding a sixth.- Calls segment. Each row shows direction (inbound / outbound), the caller or destination, duration, and a compact relative timestamp. Missed inbound calls are flagged.
- Voicemail segment. Your unread voicemail shows a dot marker. When a transcript is available, the first lines show inline. Tap a voicemail row to toggle read/unread. Tapping a voicemail does NOT open an audio player yet — that requires a native media library and is a separate roadmap item.
call_logs and voicemails tables the web Voice dashboard uses, and refresh on demand.
More
The More tab is a placeholder whose content lands in a later step (Settings will live there). Until then the app displays a quiet “This surface is coming soon.” surface in the chosen palette.Deep-link safety and push notifications
Push-derived links are routed through the navigator only when they pass the app’s deep-link allowlist, and the payload must declare the workspace you’re currently signed into. Meanwhile, the app’s Push notification settings aren’t gated by a separate toggle — a tap on a push notification that points at a valid surface will open the matching tab. The same gate guards the Inbox, Calls, and Meet tabs before the navigator accepts a URL.The deep-link allowlist
A URL carried in a push payload or a browser link must satisfy all of these before the app navigates:- Match one of three URL shapes: the
orbit://custom scheme,https://orbit.devotel.io/...(the production web app), orhttps://api.orbit.devotel.io/...(API-hosted link surfaces). - Parse as a valid URL with no control characters, no userinfo (
user@host), and no explicit port. - If it came from a push payload: the payload’s workspace identifier must equal the workspace you’re currently signed into, otherwise the link is rejected with a warning even when the URL itself is allowlisted.
deep_link, onboarding redirects, in-app “open in app” buttons) must stay inside those origins. Self-hosted dashboards or vanity domains are rejected unless they’re behind the allowlisted hosts.
Register a device for push
The app registers the OS push token against your workspace the moment sign-in completes, and re-registers whenever the OS rotates the token. If you build your own client against Orbit, reproduce this flow with two calls:- Ask the OS for the push token (APNs on iOS, FCM on Android).
- POST it to the registration endpoint:
201 with a { data, meta } envelope; data.id is the token’s Orbit identifier, and data.token is the canonical token shape stored on the row (for platform: "web" that’s the base64url-encoded Web Push envelope — reuse it on rotation instead of re-encoding).
Registration is idempotent per token: re-POSTing the same token refreshes its last-seen time and owner instead of creating a duplicate row. Pass a stable app_install_id so a reinstall retires the install’s previous token instead of leaving a zombie registration that pushes to nothing. Unregister on sign-out with DELETE /api/v1/push/device-tokens/:id.
POST /api/v1/push/register is a backwards-compatible alias with the identical request and response — older SDK clients call it; for new integrations prefer /api/v1/push/device-tokens.
To receive inbound-call (VoIP/CallKit) pushes on Android, register the same FCM token a second time against POST /api/v1/push/voip-devices with { "platform": "android", "voip_token": "<fcm-token>" }. The server dispatches to it at high priority with a call-only payload. iOS needs a real PushKit token from native code — don’t register an alert token under the VoIP topic, that registration is rejected.
Construct push payloads that open the right screen
When you send a push (POST /api/v1/push/send or a notification triggered from the dashboard), pass deep_link as a top-level field alongside title and body — a URL inside the allowed origins. Orbit attaches the sender-side workspace automatically; receiving devices only navigate when that workspace matches the one the user is signed into.
deep_link against the allowlist above before anything on screen moves — an invalid link still shows the notification, but tapping it does not navigate.