upscopeio_flutter_sdk 2026.4.5 copy "upscopeio_flutter_sdk: ^2026.4.5" to clipboard
upscopeio_flutter_sdk: ^2026.4.5 copied to clipboard

Flutter SDK for Upscope cobrowsing — screen sharing, annotations, and remote control

Upscope Flutter SDK #

Flutter plugin for Upscope cobrowsing — lets support agents view and interact with your users' screens in real-time, with no extra permissions required.

Requirements #

  • Flutter 3.19+
  • Dart SDK 3.3+
  • iOS 14.0+
  • Android API 26+ (Android 8.0)

Installation #

Add to your pubspec.yaml:

dependencies:
  upscopeio_flutter_sdk:
    git:
      url: https://github.com/upscopeio/flutter-sdk.git
      ref: main

Then run:

flutter pub get

The package is not yet published on pub.dev. The git reference above points to the public repository.

Quick Start #

1. Initialize #

Call initialize once, early in your app lifecycle (e.g. in main or your root widget's initState):

import 'package:upscopeio_flutter_sdk/upscopeio_flutter_sdk.dart';

await Upscope.instance.initialize(
  UpscopeConfiguration(apiKey: 'your_api_key'),
);

By default autoConnect: true, so the SDK connects immediately after initialization.

2. Identify the visitor #

await Upscope.instance.updateConnection(
  uniqueId: 'user-123',
  callName: 'Jane Smith',
  tags: ['premium', 'mobile'],
);

Call this any time visitor identity changes (e.g. after sign-in).

3. Show a lookup code to the user #

The lookup code lets a support agent start a session by entering a short code in the Upscope dashboard:

Upscope.instance.lookupCode.listen((code) {
  if (code != null) {
    print('Share this code with support: $code');
  }
});

That's all. The agent can now initiate a cobrowsing session from the dashboard.

Core Concepts #

Connection vs. Session #

  • Connection — persistent WebSocket link to Upscope servers. Established via connect(), torn down via disconnect(). Required before any session can start.
  • Session — an active cobrowsing window with an agent. Begins when an agent joins (or when requestAgent() is called), ends when either party stops it.

Reactive streams #

All state is exposed as Streams so you can drive your UI reactively without polling.

// Show connection status in a StreamBuilder
StreamBuilder<ConnectionState>(
  stream: Upscope.instance.connectionState,
  builder: (context, snapshot) {
    return Text(switch (snapshot.data) {
      ConnectionState.connected    => 'Ready',
      ConnectionState.connecting   => 'Connecting…',
      ConnectionState.reconnecting => 'Reconnecting…',
      ConnectionState.error        => 'Error',
      _                            => 'Offline',
    });
  },
);

Masking sensitive widgets #

Wrap any widget in UpscopeMasked to hide it from the agent's view. The region is replaced with a black rectangle in the screen capture; your users see the real content as normal.

UpscopeMasked(
  child: CreditCardField(),
)

UpscopeMasked tracks position automatically — it handles layout changes, device rotation, and scroll without any extra wiring.

Common Tasks #

Listen for session lifecycle events #

Upscope.instance.onSessionStarted.listen((_) {
  showBanner('Screen sharing started');
});

Upscope.instance.onSessionEnded.listen((reason) {
  showBanner('Session ended: $reason');
});

React to observer changes #

Upscope.instance.onObserverJoined.listen((observer) {
  print('Agent joined: ${observer.name}');
});

Upscope.instance.onObserverCountChanged.listen((count) {
  print('Observers watching: $count');
});

Request an agent #

Proactively ask for a support agent without waiting for them to initiate:

await Upscope.instance.requestAgent();

// Cancel if the user changes their mind
await Upscope.instance.cancelAgentRequest();

Stop a session #

await Upscope.instance.stopSession();

Send a custom message to the agent #

await Upscope.instance.sendCustomMessage('{"event": "checkout_started"}');

Receive messages from the agent:

Upscope.instance.onCustomMessageReceived.listen((msg) {
  print('From ${msg.observerId}: ${msg.message}');
});

Reset the connection #

Clears stored identity and reconnects (useful on sign-out):

// Reset and reconnect
await Upscope.instance.reset();

// Reset without reconnecting
await Upscope.instance.reset(reconnect: false);

Handle errors #

Upscope.instance.onError.listen((error) {
  print('Upscope error [${error.code}]: ${error.message}');
});

Configuration Reference #

All options are set once in UpscopeConfiguration passed to initialize:

Option Type Default Description
apiKey String required Your Upscope API key
autoConnect bool true Connect automatically on initialize
requireAuthorizationForSession bool true Prompt user before allowing agent to view screen
authorizationPromptTitle String 'Screen Sharing Request' Title of the consent dialog
authorizationPromptMessage String 'An agent wants to view your screen. Do you accept?' Body of the consent dialog
showBanner bool true Show an in-app banner while a session is active
showTerminateButton bool true Show a stop-sharing button in the banner
stopSessionText String 'Stop Sharing' Label on the stop-sharing button
endOfSessionMessage String? null Message shown to the user when the session ends
allowRemoteClick bool? null Override server-side remote click permission
allowRemoteScroll bool? null Override server-side remote scroll permission
requireControlRequest bool? null Require explicit user approval before agent can interact
region String? null Force a specific Upscope server region

API Reference #

Upscope.instance — methods #

Method Returns Description
initialize(UpscopeConfiguration) Future<void> Initialize and optionally auto-connect
connect() Future<void> Connect to Upscope servers
disconnect() Future<void> Disconnect from Upscope servers
reset({bool reconnect}) Future<void> Clear identity and optionally reconnect
updateConnection({uniqueId, callName, tags, identities, metadata}) Future<void> Update visitor identity
stopSession() Future<void> End the current cobrowsing session
requestAgent() Future<void> Request a support agent
cancelAgentRequest() Future<void> Cancel a pending agent request
getLookupCode() Future<void> Trigger a lookup code refresh
getShortId() Future<String?> Get the persistent visitor short ID
getWatchLink() Future<String?> Get a direct watch link for the current session
sendCustomMessage(String) Future<void> Send a custom string to all connected agents

Upscope.instance — streams #

Stream Type Emits
connectionState Stream<ConnectionState> Connection state changes
sessionState Stream<SessionState> Session state changes
lookupCode Stream<String?> Current lookup code (refreshes periodically)
shortId Stream<String?> Persistent visitor short ID
onSessionStarted Stream<String?> Session ID when a session begins
onSessionEnded Stream<SessionEndReason> Reason the session ended
onObserverJoined Stream<Observer> Agent joined the session
onObserverLeft Stream<String> Agent ID when an agent leaves
onObserverCountChanged Stream<int> Current number of watching agents
onCustomMessageReceived Stream<CustomMessage> Custom message from an agent
onError Stream<UpscopeError> SDK-level errors

Enums #

ConnectionStateinactive, connecting, connected, reconnecting, error

SessionStateinactive, pendingRequest, active, paused, ended

SessionEndReasonuserStopped, agentStopped, timeout, error

Widgets #

UpscopeMasked({required Widget child}) — Wraps a child and masks its screen region during cobrowsing. Handles position tracking, rotation, and scroll automatically. No configuration needed.

Troubleshooting #

Sessions never start / connection stays inactive

  • Confirm autoConnect: true (default) or that you called connect() explicitly.
  • Verify the API key is correct for your Upscope account.
  • Check that the device has internet access.

Streams receive no events

  • Subscribe to streams before calling initialize, or use a StreamController with sync: false to avoid missing the first emission.

Masked widget position is wrong after navigation

  • UpscopeMasked tracks metrics changes and scroll, but not route transitions. If you push/pop routes while a masked widget is off-screen, the rect will be corrected on the next frame when the widget is visible again. This is typically transparent to the agent.

iOS build fails with missing plugin

  • Ensure you have run pod install (or flutter pub get which runs it for you).
  • The plugin class is UpscopePlugin registered under the io.upscope.flutter namespace.

Android build fails

  • Minimum supported API is 26. Check minSdk in your app-level build.gradle.

Support #

License #

Proprietary. See your agreement with Upscope for details.

0
likes
0
points
608
downloads

Publisher

verified publisherupscope.io

Weekly Downloads

Flutter SDK for Upscope cobrowsing — screen sharing, annotations, and remote control

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on upscopeio_flutter_sdk

Packages that implement upscopeio_flutter_sdk