utd_signaling
The UTD-Stream signalling plane for Flutter — the shared, no-UI foundation
under utd_calls_kit / utd_chat_kit and future kits. It owns the REST +
WebSocket transport: per-user session mint, presence, 1:1 call invitations, chat
messaging + groups, typing, push-token registration, and media-upload presign.
No media (LiveKit/WebRTC), no UI, no local storage.
Most consumers use the high-level UTDSignaling facade; the lower-level
UTDApi / UTDSignalClient remain available for kits that need the full
surface.
Capabilities & billing
UTD-Stream exposes two independent, separately-billed capabilities:
| Capability | What it covers | Engine flag |
|---|---|---|
signaling |
Call invitation + presence + rooms/broadcast | signaling_enabled |
chat |
Persistent 1:1/group messaging + history + receipts | messaging_enabled |
Each is sold via a subscription plan (Free / Signaling / Pro / Enterprise) with
per-plan limits: history_days, max_group_members, max_friends,
max_chatrooms. Billing is MAU-based — there is no per-message charge.
Session capability surfacing
The session mint (POST /api/v1/auth/session) may carry the capability flags +
plan limits. They are parsed defensively and are all nullable — a null
flag means the engine didn't surface it (older engine); treat it as "unknown,
let the server decide", distinct from an explicit false.
final signaling = UTDSignaling(appId: 'app_x', appKey: 'key_x', userId: 'alice');
await signaling.connect();
if (signaling.signalingEnabled == false) {
// Paid `signaling` capability is off for this plan — show an upsell.
}
final days = signaling.planLimits?.historyDays; // history retention, when known
UTDSignaling exposes signalingEnabled, chatEnabled, and planLimits
(a UTDPlanLimits with historyDays / maxGroupMembers / maxFriends /
maxChatrooms), captured on every (re)connect. UTDApi.mintSession() returns
the same flags + limits on its result record.
A paid-capability gate from the engine (a non-ban 403 saying a capability is
"not enabled") surfaces as UTDStreamException with
code == UTDErrorCode.featureDisabled; branch on isFeatureDisabled (or
isSignalingDisabled / isChatDisabled) to show an upsell instead of a raw
failure. isForbidden still returns true for it.
Libraries
- utd_signaling
- UTD-Stream signalling plane for Flutter.