The TypeScript SDK ships five modality sub-imports plus a raw MoQT client and a legacy RPC client. Each sub-import is its own client class with its own options.
import { Voice }      from "@clutchcall/sdk/voice";
import { Streams }    from "@clutchcall/sdk/streams";
import { Robotics }   from "@clutchcall/sdk/robotics";
import { Games }      from "@clutchcall/sdk/games";
import { Data }       from "@clutchcall/sdk/data";
import { MoqtClient } from "@clutchcall/sdk/moqt";

Voice

const v = new Voice({
  baseUrl:        "https://app.clutchcall.dev",   // control-plane API base
  apiKey?:        string,    // server-side
  browserToken?:  string,    // browser-side
  orgId?:         string,
});

Calls (control plane)

await v.calls.originate({
  to:       string,                 // E.164
  from?:    string,                 // E.164
  trunkId?: string,                 // your trunk
  agent?:   string,                 // AI agent name (optional)
}) → Call

await v.calls.get(sid)                          → Call
await v.calls.list({ orgId?, cursor?, limit? }) → { calls, cursor? }
await v.calls.transfer(sid, { to, trunkId? })   → Call
await v.calls.hangup(sid)                       → void
await v.calls.terminate(sid)                    → void
Call exposes:
call.sid:    string
call.status: CallStatus
call.from:   string
call.to:     string

call.onStatus((s: CallStatus) => void): Unsubscribe
await call.refresh(): Promise<CallData>
await call.hangup(): Promise<void>
await call.transfer(args): Promise<Call>

AudioBridge (data plane)

const bridge = await v.audioBridge.attach(callSid, {
  codec:      "opus" | "pcm16" | "g711_ulaw" | "g711_alaw",
  onUplink?:  (frame: Uint8Array, tsUs: bigint) => void,
});

bridge.publishUplink(frame: Uint8Array): void   // browser → cloud
bridge.publishDownlink(frame: Uint8Array): void // cloud → caller
bridge.onUplink(cb): Unsubscribe
bridge.onDownlink(cb): Unsubscribe
await bridge.close(): Promise<void>
Browser helpers:
import { captureMicrophone, OpusPlayer } from "@clutchcall/sdk/voice";

const mic    = await captureMicrophone({ onFrame: f => bridge.publishUplink(f) });
const player = new OpusPlayer();
bridge.onDownlink(f => player.play(f));

Agents

await v.agents.attach(callSid, agentName): Promise<void>
await v.agents.detach(callSid): Promise<void>
await v.agents.list({ orgId? }): Promise<Agent[]>

Streams

const streams = new Streams({
  baseUrl:  "https://app.clutchcall.dev",
  apiKey:   string,
  orgId:    string,
});

Control plane

streams.liveInputs.create({ name, codecs?, recordingProfile? })
                                                → { input, streamKey }   // streamKey returned ONCE
streams.liveInputs.get({ id })                  → LiveInput
streams.liveInputs.list({ orgId, cursor?, limit? }) → { liveInputs, cursor? }
streams.liveInputs.rotateStreamKey({ id })      → { streamKey }
streams.liveInputs.delete({ id })               → void

streams.signingKeys.create({ orgId, label })    → { id, keyMaterial }
streams.signingKeys.list({ orgId })             → SigningKey[]
streams.signingKeys.retire({ id })              → void

streams.apiKeys.create({ orgId, label, scopes }) → { id, secret }       // secret returned ONCE
streams.apiKeys.list({ orgId })                  → ApiKey[]
streams.apiKeys.revoke({ id })                   → void

streams.webhooks.create({ orgId, url, events })  → Webhook
streams.webhooks.list({ orgId })                 → Webhook[]
streams.webhooks.delete({ id })                  → void
streams.events.listDeliveries({ webhookId, cursor?, limit? }) → { deliveries, cursor? }

streams.analytics.viewerMinutes({ orgId, from, to, groupBy? }) → ViewerMinutesRow[]
streams.analytics.popCache({ orgId, from, to })   → PopCacheRow[]
LiveInput exposes:
input.external_input_id: string
await input.signedPlaybackUrl({ ttlSeconds: number, scopes? }) → { url, expiresAt }

Data plane

const pub = await BroadcastPublisher.open({
  inputId:   string,
  streamKey: string,                  // from create() / rotateStreamKey()
  codecs:    { video: string, audio: string },
});
pub.write(chunk: Uint8Array): void
await pub.close(reason?: string): Promise<void>

const viewer = await BroadcastViewer.open(signedUrl, {
  onChunk: (init: BroadcastInit, chunk: BroadcastChunk) => void,
  onClose: (reason: string) => void,
});
await viewer.close(): Promise<void>

Robotics

const r = new Robotics({
  relayHost: "relay.clutchcall.dev",
  token:     string,
  robotId:   string,        // unique per (tenant, robot)
});
// publish
await r.publishTelemetry({
  topic:    string,                       // e.g. "odom"
  typeName: string,                       // e.g. "nav_msgs/msg/Odometry"
  qos?:     QoSProfile,
}) → RoboticsPublication

await r.publishCommand({
  topic:    string,                       // e.g. "cmd_vel"
  typeName: string,                       // e.g. "geometry_msgs/msg/Twist"
  qos?:     QoSProfile,
}) → RoboticsPublication

// subscribe
await r.subscribeTelemetry({ topic, qos? },
  (payload: Uint8Array, typeName: string) => void) → RoboticsSubscription
await r.subscribeCommand   ({ topic, qos? },
  (payload: Uint8Array, typeName: string) => void) → RoboticsSubscription
RoboticsPublication:
pub.write(cdrBytes: Uint8Array): void
await pub.close(): Promise<void>
QoSProfile:
{
  reliability?: "reliable" | "best_effort";
  durability?:  "volatile"  | "transient_local";
  depth?:       number;
}

Games

const g = new Games({
  relayHost: "relay.clutchcall.dev",
  token:     string,
  roomId:    string,
  playerId?: string,        // omit for the authoritative server
});

Player

g.subscribeState((bytes: Uint8Array) => void): GamesSubscription
const input = await g.publishInput(): FromPublisher
input.write(bytes: Uint8Array): void

const events = await g.publishEvent(): FromPublisher
events.send(obj: any): void
g.subscribeEvents((event: any, fromPlayerId: string) => void): GamesSubscription

Authority (no playerId)

const state = await g.publishState({ tickHz?: number }): StatePublisher
state.write(bytes: Uint8Array): void

await g.subscribeInputs((playerId: string, bytes: Uint8Array) => void): GamesSubscription
await g.subscribeEvents((event: any, fromPlayerId: string) => void): GamesSubscription

Data

const d = new Data({
  relayHost: "relay.clutchcall.dev",
  token:     string,
  clientId:  string,        // your publisher identity
});
await d.publish({
  topic:     string,
  payload:   Uint8Array,
  reliable?: boolean,                     // default false → datagram
  retain?:   boolean,                     // last-value-stuck
}): void

await d.subscribe({ topicFilter: string }, (msg: DataMessage) => void)
                                                          : DataSubscription
DataMessage:
{
  topic:        string;        // the actual topic published to
  payload:      Uint8Array;
  fromClientId: string;
  retain:       boolean;
  tsUs:         bigint;
}
Topic filters support MQTT-style + (one segment) and # (multi-segment, trailing only).

Realtime Tracks

The raw substrate. See Realtime Tracks for the full surface. Common methods:
const moqt = await MoqtClient.connect(relayUrl, token, onState);

moqt.publishFrame(namespace, name, opts?: FrameOptions): FramePublication
moqt.subscribeFrame(namespace, name, cb): FrameSubscription
moqt.publishAudio(namespace, name, opts?: AudioOptions): AudioPublication
moqt.subscribeAudio(namespace, name, cb): AudioSubscription
moqt.publishVideo(namespace, name, opts?: VideoOptions): VideoPublication
moqt.subscribeVideo(namespace, name, cb): VideoSubscription
moqt.publishText(namespace, name, opts?: TextOptions): TextPublication
moqt.subscribeText(namespace, name, cb): TextSubscription

moqt.subscribeNamespace(prefix: string[],
  (suffix: string, active: boolean) => void): void
moqt.connectionRttUs(): bigint
moqt.maxDatagramSize(): number
moqt.close(): void

Legacy RPC

The root import is the legacy voice-RPC surface (dial, originate_bulk, hangup, barge, push_audio, …). Documented for backwards compat — new code should use the Voice modality.
import { ClutchCallClient } from "@clutchcall/sdk";

const client = new ClutchCallClient("https://pbx.clutchcall.dev");
await client.dial(/* ... */);
await client.hangup(/* ... */);
See the SDK split repo for the full legacy surface.