The Soniox community adapter calls Soniox speech-to-text from generateTranscription(). It supports speaker labels, language detection, custom terms, and translation. Soniox maintains it.
npm i @soniox/tanstack-ai-adapterpnpm add @soniox/tanstack-ai-adapteryarn add @soniox/tanstack-ai-adapterbun add @soniox/tanstack-ai-adapterGet your API key from the Soniox Console. Put it in the environment of your server:
SONIOX_API_KEY=your-api-keysonioxTranscription reads SONIOX_API_KEY. To pass the key in code, use createSonioxTranscription:
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",
});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.
Soniox detects and transcribes speech in 60+ languages. Do you know which languages the audio has? Pass them in languageHints to improve accuracy:
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",
});See the Soniox language hints docs.
Context helps the model know your domain and your important terms. It improves transcription and translation:
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:
See the Soniox context docs.
One-way translation:
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:
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.
Pass these in modelOptions:
| Option | What it does |
|---|---|
| languageHints | An array of ISO language codes that bias recognition. |
| languageHintsStrict | When true, rely more on the language hints. Not all models support it. |
| enableLanguageIdentification | Detect the spoken language. |
| enableSpeakerDiarization | Find and label the different speakers. |
| context | More context, to improve accuracy. See Context. |
| translation | The translation settings. See Translation. |
| clientReferenceId | An optional reference ID of your own. |
| webhookUrl | A webhook URL that gets a call when the transcription is done. |
| webhookAuthHeaderName | The name of the auth header for the webhook. |
| webhookAuthHeaderValue | The value of the auth header for the webhook. |
See the Soniox API reference.
Pass these to createSonioxTranscription:
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,
});| Option | What it does |
|---|---|
| apiKey | Overrides SONIOX_API_KEY. Required with createSonioxTranscription. |
| baseUrl | A custom API base URL. Default https://api.soniox.com. |
| headers | More request headers. |
| timeout | The transcription timeout in milliseconds. Default 180000. |
| pollingIntervalMs | How often the adapter checks the transcription status, in milliseconds. Default 1000. |
For data residency, see the Soniox regional endpoints.
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:
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:
For all of the Soniox API, see the Soniox docs.