pipedog is an unofficial community port of Pipecat, not affiliated with Daily.
pipedog
Speech-to-text

AWS Transcribe

Streaming speech-to-text from Amazon Transcribe with AWSTranscribeSTTService, over Transcribe's WebSocket API.

Overview

AWSTranscribeSTTService streams the user's audio to Amazon Transcribe and emits interim and final transcripts. It connects to Transcribe's WebSocket API with a SigV4-presigned URL and sends audio as event-stream AudioEvent messages, as upstream does.

Installation

bun add @pipedog/aws
import { AWSTranscribeSTTService } from "@pipedog/aws/stt";

Prerequisites

  • An IAM identity allowed transcribe:StartStreamTranscriptionWebSocket.

  • Keys, in this order of precedence:

    1. awsAccessKeyId, apiKey (the secret access key) and awsSessionToken.
    2. The AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN environment variables.
    3. A credentialsProvider function, called for every connection, so each URL is signed with current keys.

    The region comes from region, else AWS_REGION, else us-east-1.

AWSTranscribeSTTService

Configuration

Prop

Type

Settings

Runtime-updatable settings, passed as settings: new AWSTranscribeSTTService.Settings({...}). Transcribe binds them to the connection, so changing one reconnects.

SettingTypeDefaultDescription
languageLanguageLanguage.ENTranscription language, mapped to a Transcribe code (en-US, es-ES, …).
partialResultsStability"high" | "medium" | "low""high"Stability of interim results: "high" is fastest, "low" most accurate.
modelstring | nullnullNot used by Transcribe.

Usage

stt.ts
import { AWSTranscribeSTTService } from "@pipedog/aws/stt";
import { STTUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { Language } from "@pipedog/core/transcriptions/language";

const stt = new AWSTranscribeSTTService({
  // Or leave these out to read AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
  // AWS_SESSION_TOKEN and AWS_REGION from the environment.
  awsAccessKeyId: process.env.AWS_ACCESS_KEY_ID,
  apiKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: "us-east-1",
  sampleRate: 16000,
  settings: new AWSTranscribeSTTService.Settings({
    language: Language.EN_US,
    partialResultsStability: "medium",
  }),
});

Change the language mid-call with an STTUpdateSettingsFrame:

// Queue it on the worker, or push it from a processor upstream of the service.
// Transcribe binds the language to the connection, so this reconnects.
const update = new STTUpdateSettingsFrame({
  delta: new AWSTranscribeSTTService.Settings({ language: Language.ES_ES }),
});

Event handlers

EventDescription
on_connectedThe WebSocket to Transcribe is open.
on_disconnectedThe WebSocket to Transcribe closed.
on_connection_errorConnecting failed. Receives the error message.

Notes

  • Emits InterimTranscriptionFrames for partial results and a TranscriptionFrame for each final result.
  • Transcribe accepts 8000 or 16000 Hz PCM. Another sampleRate (or pipeline rate) is replaced by 16000 Hz on connect, with a warning.
  • Partial-result stabilization is always on; partialResultsStability sets its level.
  • On disconnect the service sends upstream's end-of-stream message before closing the socket.
  • A 401 or 403 from Transcribe is reported as a connectivity error, as upstream does.

Runtime notes

RuntimeWorksWhat it needs
Bun✅ yesNothing.
Node.js✅ yesNothing.
Deno✅ yesNothing.
Cloudflare Workers✅ yesNothing.

Generated from pipecat.runtimes and pipecat.compat in packages/aws/package.json: ✅ means the compat smoke test passes on that runtime.

  • Runs on Bun, Node, Deno and Cloudflare Workers. The URL is presigned with SigV4 on WebCrypto, and the socket is the global WebSocket (opened through fetch on Workers).
  • Only the Origin handshake header is sent; the runtime's WebSocket sets the others.
  • There is no default AWS credential chain (profiles, IMDS, ECS roles, SSO). Use keys, the environment, or credentialsProvider.
  • endpointUrl replaces wss://transcribestreaming.<region>.amazonaws.com:8443, for a proxy or a local fake. The URL is still signed for the AWS host.
  • Not ported: the deprecated language constructor option. Use settings.language.

pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.

Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).

On this page