# Quickstart

> Pick a modality and build a working app in less than five minutes.

FirstByte is **modality-oriented**. Pick the modality that matches what
you build: voice, streams, robotics, games, or data. Then import its
sub-client. All five modalities use the same MoQT relay mesh.

This page shows a worked example in TypeScript. Each [per-language
quickstart](/sdks/overview) shows the same pattern in that SDK's idiom.

## 1. Install

```bash npm
npm install clutchcall_connect
```

The package includes the WASM core. The browser needs no separate native
install. Native Node / Python / Go / Rust / Java / .NET SDKs also load
`clutchcall_core_ffi.{so,dylib,dll}`. See each per-language [installation
page](/sdks/overview).

## 2. Get a token

Every modality authenticates with a **tenant token**. The relay checks
the token through its namespace-auth hook. The control-plane API key
(tRPC, `CLUTCHCALL_CREDENTIALS`) mints data-plane tokens. Each token is
scoped to the namespaces that the client needs.

```bash
export CLUTCHCALL_API_KEY=...           # server-side control-plane API key
export CLUTCHCALL_RELAY_TOKEN=...       # data-plane tenant token
```

See [Authentication](/concepts/authentication) for the full key model
(API key → relay token mint → namespace-scoped JWT).

## 3. Pick a modality

**Voice — originate a call:**
```ts
import { Voice } from "clutchcall_connect/voice";

const v    = new Voice({ baseUrl: "https://portal.firstbyte.fast",
                         apiKey:  process.env.CLUTCHCALL_API_KEY!,
                         orgId:   "org_abc" });
const call = await v.calls.originate({
  to: "+15551234567", from: "+15558675309",
  trunkId: "trunk_main", agent: "healthcare-assistant",
});
console.log("call sid:", call.sid);
```

**Streams — watch a broadcast:**
```ts
import { Streams, BroadcastViewer } from "clutchcall_connect/streams";

const streams       = new Streams({ baseUrl: BASE_URL, apiKey: KEY, orgId: ORG });
const input         = await streams.liveInputs.get({ id: "li_xyz" });
const { url }       = await input.signedPlaybackUrl({ ttlSeconds: 3600 });

const viewer = await BroadcastViewer.open(url, {
  onChunk: (init, chunk) => buffer.appendBuffer(chunk.data),
});
```

**Robotics — publish odometry:**
```ts
import { Robotics } from "clutchcall_connect/robotics";

const r    = new Robotics({ relayHost: "relay.firstbyte.fast",
                            token: process.env.CLUTCHCALL_RELAY_TOKEN!,
                            robotId: "turtlebot-7" });
const odom = await r.publishTelemetry({
  topic: "odom", typeName: "nav_msgs/msg/Odometry",
});
odom.write(cdrBytes);
```

**Games — player joining a room:**
```ts
import { Games } from "clutchcall_connect/games";

const me    = new Games({ relayHost: "relay.firstbyte.fast", token,
                          roomId: "duel-42", playerId: "alice" });
me.subscribeState(bytes => render(deserializeState(bytes)));
const input = await me.publishInput();
addEventListener("tick", () => input.write(serializeInput(localInput)));
```

**Data — MQTT-style pub/sub:**
```ts
import { Data } from "clutchcall_connect/data";

const d = new Data({ relayHost: "relay.firstbyte.fast", token,
                     clientId: "device-7" });
await d.publish({ topic: "sensors/room1/temp",
                  payload: new TextEncoder().encode("23.5") });
await d.subscribe({ topicFilter: "sensors/+/temp" }, msg => {
  console.log(msg.topic, "←", msg.fromClientId);
});
```

## What just happened

1. The SDK opened a QUIC link to `relay.firstbyte.fast:443` over MoQT.
   In the browser, the SDK used WebTransport. The tenant token authorized
   the session.
2. For control-plane modality methods (`v.calls.originate`,
   `streams.liveInputs.create`, etc.), the SDK called tRPC procedures on
   the control-plane API over HTTP/3.
3. For data-plane methods (`subscribeState`, `publishInput`, etc.), the SDK
   opened MoQT publish / subscribe requests. The relay fans these out to
   every matching subscriber.

The same connection survives reconnects. See
[Realtime Tracks](/concepts/realtime-tracks) for the auto-reconnect model.

## Next steps

  - **[Modalities overview](/modalities/overview)** — The five-modality model and when to pick each modality.
  - **[Architecture](/concepts/architecture)** — The MoQT relay mesh, the C++ core, and how the modality layer fits.
  - **[Authentication](/concepts/authentication)** — API keys, relay tokens, namespace-auth, and JWT signing.
  - **[SDK Reference](/sdks/overview)** — A reference for every modality, every method, and every language.
