Skip to content
Community Adapters

Soniox

The Soniox community adapter calls Soniox speech-to-text from generateTranscription(). It supports speaker labels, language detection, custom terms, and translation. Soniox maintains it.

1. Install

shell
npm i @soniox/tanstack-ai-adapter

2. Set the API key

Get your API key from the Soniox Console. Put it in the environment of your server:

shell
SONIOX_API_KEY=your-api-key

sonioxTranscription reads SONIOX_API_KEY. To pass the key in code, use createSonioxTranscription:

ts
import { generateTranscription } from "@tanstack/ai";
import { createSonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audioFile } from "./audio";

const adapter = createSonioxTranscription("stt-async-v3", process.env.SONIOX_API_KEY!);

const result = await generateTranscription({
  adapter,
  audio: audioFile,
  threadId: "thread-1",
});

3. Transcribe audio

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audioFile } from "./audio";

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio: audioFile,
  modelOptions: {
    enableLanguageIdentification: true,
    enableSpeakerDiarization: true,
  },
  threadId: "thread-1",
});

console.log(result.text);
console.log(result.segments);

You get the full text in result.text, and the timed segments with speaker labels in result.segments. See Transcription.

Language hints

Soniox detects and transcribes speech in 60+ languages. Do you know which languages the audio has? Pass them in languageHints to improve accuracy:

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audio } from "./audio";

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio,
  modelOptions: {
    languageHints: ["en", "es"],
  },
  threadId: "thread-1",
});
  • Hints do not limit recognition. They only bias it.
  • If you pass the TanStack language option, the adapter adds it to languageHints.

See the Soniox language hints docs.

Context

Context helps the model know your domain and your important terms. It improves transcription and translation:

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audio } from "./audio";

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio,
  modelOptions: {
    context: {
      general: [
        { key: "domain", value: "Healthcare" },
        { key: "topic", value: "Diabetes management consultation" },
        { key: "doctor", value: "Dr. Martha Smith" },
      ],
      text: "The patient has a history of...",
      terms: ["Celebrex", "Zyrtec", "Xanax"],
      translationTerms: [
        { source: "Mr. Smith", target: "Sr. Smith" },
        { source: "MRI", target: "RM" },
      ],
    },
  },
  threadId: "thread-1",
});

All four sections are optional:

  • general: key and value pairs about the audio.
  • text: free text about the audio.
  • terms: words to recognize.
  • translationTerms: fixed translations for terms.

See the Soniox context docs.

Translation

One-way translation:

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audio } from "./audio";

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio,
  modelOptions: {
    translation: {
      type: "one_way",
      targetLanguage: "es",
    },
  },
  threadId: "thread-1",
});

Two-way translation:

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audio } from "./audio";

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio,
  modelOptions: {
    translation: {
      type: "two_way",
      languageA: "en",
      languageB: "es",
    },
  },
  threadId: "thread-1",
});

With translation, the API returns transcription tokens and translation tokens. segments holds only the transcription tokens. To get the translation tokens, read the raw tokens and keep the ones where translation_status === "translation". See Raw tokens.

Models and options

Transcription options

Pass these in modelOptions:

OptionWhat it does
languageHintsAn array of ISO language codes that bias recognition.
languageHintsStrictWhen true, rely more on the language hints. Not all models support it.
enableLanguageIdentificationDetect the spoken language.
enableSpeakerDiarizationFind and label the different speakers.
contextMore context, to improve accuracy. See Context.
translationThe translation settings. See Translation.
clientReferenceIdAn optional reference ID of your own.
webhookUrlA webhook URL that gets a call when the transcription is done.
webhookAuthHeaderNameThe name of the auth header for the webhook.
webhookAuthHeaderValueThe value of the auth header for the webhook.

See the Soniox API reference.

Adapter options

Pass these to createSonioxTranscription:

ts
import { createSonioxTranscription } from "@soniox/tanstack-ai-adapter";

const adapter = createSonioxTranscription("stt-async-v3", process.env.SONIOX_API_KEY!, {
  baseUrl: "https://api.soniox.com",
  pollingIntervalMs: 1000,
  timeout: 180000,
});
OptionWhat it does
apiKeyOverrides SONIOX_API_KEY. Required with createSonioxTranscription.
baseUrlA custom API base URL. Default https://api.soniox.com.
headersMore request headers.
timeoutThe transcription timeout in milliseconds. Default 180000.
pollingIntervalMsHow often the adapter checks the transcription status, in milliseconds. Default 1000.

For data residency, see the Soniox regional endpoints.

Advanced

Raw tokens

For translation or audio with many languages, you can need the raw tokens. Each one has its language and its translation status. The adapter adds a non-standard providerMetadata field at run time. It is not on the TranscriptionResult type, so narrow it with in checks:

ts
import { generateTranscription } from "@tanstack/ai";
import { sonioxTranscription } from "@soniox/tanstack-ai-adapter";
import { audio } from "./audio";

function sonioxTokens(result: object): Array<unknown> {
  if (!("providerMetadata" in result)) return [];
  const metadata = result.providerMetadata;
  if (typeof metadata !== "object" || metadata === null) return [];
  if (!("soniox" in metadata)) return [];
  const soniox = metadata.soniox;
  if (typeof soniox !== "object" || soniox === null) return [];
  if (!("tokens" in soniox) || !Array.isArray(soniox.tokens)) return [];
  return soniox.tokens;
}

const result = await generateTranscription({
  adapter: sonioxTranscription("stt-async-v3"),
  audio,
  modelOptions: {
    translation: { type: "one_way", targetLanguage: "es" },
  },
  threadId: "thread-1",
});

for (const token of sonioxTokens(result)) {
  console.log(token);
}

Each token has these fields:

  • text: the token text.
  • start_ms and end_ms: the start and end time in milliseconds.
  • language: the detected language of the token.
  • translation_status: the translation status, when translation is on.
  • speaker: the speaker id.
  • confidence: the confidence score.

For all of the Soniox API, see the Soniox docs.