> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corti.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Capture microphone audio with the SDK

> Drive the Transcribe API directly with the Corti SDK while your app manages the microphone

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/d6WKOaS9_Ts?start=67&end=133" title="Capture Microphone Audio with the SDK — walkthrough" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowFullScreen />

<Info>
  **Follow along with the runnable example.** This guide walks through the [Raw SDK mic example](https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-sdk) in `corti-examples` — bootstrap your build from it or use it as reference.
</Info>

This guide shows how to wire your **own microphone controls** to the Corti SDK for real-time dictation. Your application owns audio capture — the record button, device selection, level metering — and streams frames to the [Transcribe API](/api-reference/transcribe) through an SDK socket.

Use this approach when you already have microphone handling in your app, or need lower-level control than a prebuilt UI provides.

<Tip>
  If you don't need to own the microphone yourself, the [Dictation Web Component](/sdk/dictation/overview) handles recording device management, streaming, and the transcript UI for you. It is the recommended starting point and is used throughout the rest of these guides. Reach for the raw SDK only when you need to integrate existing mic controls or build a fully custom interface.
</Tip>

***

## How it works

The SDK wraps the Transcribe WebSocket with a promise-based `connect()`. The flow is:

<Steps titleSize="h3">
  <Step title="Construct the client">
    Create a `CortiClient` with your auth. See the [raw SDK mic example](https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-sdk) in `corti-examples` for the setup code.
  </Step>

  <Step title="Connect and send configuration">
    Call `client.transcribe.connect({ configuration })`. The promise resolves **only after** the server returns `CONFIG_ACCEPTED`, so audio is never sent before the handshake completes.
  </Step>

  <Step title="Stream audio frames">
    Capture the microphone with `MediaRecorder` and pass each chunk's `arrayBuffer()` to `socket.sendAudio()`.
  </Step>

  <Step title="Handle transcripts">
    Listen for `transcript` messages and insert the text into your target field.
  </Step>
</Steps>

***

## Prerequisites

* The Corti SDK: `npm install @corti/sdk`
* A token source that returns `{ accessToken, expiresIn }`. See the [Authentication guide](/sdk/js/authentication) for the available flows.

See the [raw SDK mic example](https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-sdk) in `corti-examples` for client construction and socket connection — the examples below focus on the audio capture side.

***

## Capture the microphone

Request the microphone with `getUserMedia`, then feed `MediaRecorder` output to the socket. A short timeslice (100–250 ms) keeps latency low.

```ts title="JavaScript" theme={null}
const TIMESLICE_MS = 250;

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

const recorder = new MediaRecorder(stream);
recorder.ondataavailable = async (e) => {
  if (e.data.size > 0) {
    // pass e.data.arrayBuffer() to socket.sendAudio()
  }
};
recorder.start(TIMESLICE_MS);
```

<Tip>
  To drive an audio-level meter, tap the same `MediaStream` with a Web Audio `AnalyserNode` — no extra permission or second capture is required.
</Tip>

***

## Stop and clean up

On stop or unmount, stop the recorder and release the microphone tracks. Also close the SDK socket so the session ends cleanly.

```ts title="JavaScript" theme={null}
function stop() {
  if (recorder.state !== "inactive") recorder.stop();
  stream.getTracks().forEach((t) => t.stop());
}
```

<Warning>
  Always release the `MediaStream` tracks and close the SDK socket. Leaving the microphone open holds the OS recording indicator and keeps the WebSocket session billing/active.
</Warning>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Text Insertion" icon="text-cursor" href="/stt/guides/dictation-text-insertion">
    Insert transcripts into a target field with correct spacing and casing.
  </Card>

  <Card title="Dictation Web Component" icon="microphone" href="/sdk/dictation/overview">
    Skip manual mic handling with a prebuilt, styleable dictation UI.
  </Card>

  <Card title="Example code" icon="github" href="https://github.com/corticph/corti-examples/tree/main/sdk/typescript/applets/src/applets/dictation-sdk">
    The complete, runnable Raw SDK mic example in `corti-examples`.
  </Card>
</CardGroup>

<Note>Please [contact us](mailto:help@corti.ai) for help or questions.</Note>
