session.transcription turns what the user says into text. Register a handler and you start getting results; the SDK handles the subscription for you.
Transcription needs the MICROPHONE permission in your manifest. Without it, the phone rejects the subscription with PERMISSION_NOT_DECLARED and no events arrive.

Results

Each event is a TranscriptionData: Interim results stream as the user speaks and get replaced; wait for isFinal if you only want settled text.

Targeting languages

on() auto-detects the language. To listen for specific ones, use forLanguage() with BCP-47 tags:
Each call is independent, and you can have several active at the same time.

Requiring on-device transcription

Pass {forceLocal: true} as the final argument to route that subscription through on-device STT and suppress cloud transcript delivery:
This requires a downloaded local STT model. Cloud transcripts are suppressed for the local-only subscription, even while other miniapps continue using cloud transcription. Routing is per listener, so a default listener on the same stream can continue receiving cloud transcription.

Configuring

configure() tunes the recognizer. It’s fire-and-forget and applies to subsequent results:

Cleaning up

Every subscription returns an unsubscribe function. stop() tears down every subscription this module owns at once:
session.transcription.hasPermission tells you whether MICROPHONE is declared in your manifest. It does not tell you whether the user granted the OS prompt: if they denied it, your handler simply never fires. See Permissions.
Transcription is for text. For raw audio frames or voice-activity detection, use session.mic. For translated text, use session.translation. Subscribing to one does not subscribe you to the others.