Skip to main content
Vexa sends meeting audio to one OpenAI-compatible speech-to-text endpoint. The endpoint can be the bundled faster-whisper service, Vexa’s hosted transcription service, or a self-hosted gateway that implements the same request shape. Use this path when you want a different ASR model without changing the bot, meeting-api, or live transcript pipeline. Don’t have a key yet? Hosted: sign in at vexa.ai/signin with a Google account and copy your key from your account page — free credit, no card required. Self-hosted: make all prints a key when the stack comes up. To transcribe later instead — or on hardware Vexa never talks to — send the bot with transcription off and collect the audio afterwards: Capture now, transcribe later.

Contract

Vexa appends /v1/audio/transcriptions to TRANSCRIPTION_SERVICE_URL and sends multipart form data: The minimum response Vexa needs is:
Backends may include segments, words, timestamps, duration, or usage metadata. Keep those fields additive: the meeting pipeline must still work when only text is present.

Configure Vexa

Set these variables in deploy/compose/.env:
TRANSCRIPTION_SERVICE_URL is the base URL. Do not include /v1/audio/transcriptions; Vexa appends that path. If the backend ignores the model form part, leave TRANSCRIPTION_MODEL unset. If it validates model ids, set the exact served name.

Before you swap: the bundled model has a knob

The bundled faster-whisper service chooses its model from MODEL_SIZE, which defaults to large-v3-turbo (core/meetings/services/transcription/src/transcription/main.py). Turbo is a faster, lighter distillation of large-v3 — it trades some accuracy for speed and VRAM, and how much depends on the language. If accuracy on yours matters more than latency, change one variable before you go looking for a different engine:
Set it on the transcription unit (deploy/transcription/.env), not on the main stack. That unit ignores the model form part a caller sends and serves whatever MODEL_SIZE names, so TRANSCRIPTION_MODEL has no effect on it — TRANSCRIPTION_MODEL exists for backends that validate a model id. See deploy/transcription/README.md.

Example: FunASR or SenseVoice

Client path validated upstream; complete meeting deployment still needs a witness. The FunASR maintainers ran Vexa’s own TranscriptionClient against the FunASR 1.3.26 OpenAI-compatible server with SenseVoice on CPU (#928). Chinese, English, Cantonese, Japanese, Korean, and concatenated Chinese-English samples all produced non-empty transcripts, verbose segments, and duration metadata. No Vexa maintainer has reproduced this — a bot-in-meeting run and the platform_settings override path remain unwitnessed on either side, and are tracked in #863.
A self-hosted FunASR/SenseVoice gateway is a working example of this contract: a real non-Vexa backend that has been run against Vexa’s own client and answered with non-empty verbose responses. That is a claim about portability, not about quality. Which model transcribes your languages best is your decision — Vexa does not benchmark third-party models. Measure your own audio before you switch. Run or deploy a gateway that accepts:
Then point Vexa at the same host:
The official funasr-server --model sensevoice exposes sensevoice as its served model id. A Hub checkpoint path such as FunAudioLLM/SenseVoiceSmall is not automatically an API model id; verify the names exposed by your gateway’s GET /v1/models route. The official Fun-ASR-Nano server uses fun-asr-nano. Other gateways may expose different names.
FunASR 1.3.26 transcribes all five languages correctly, but when language is omitted it reports language: "zh" for every verbose response. Pin the meeting language when accurate metadata matters. The upstream fix is tracked in modelscope/FunASR#3400.
Vexa treats the STT service as a network dependency. Put the ASR runtime on a GPU box if needed, and keep the main stack CPU-only.

Preflight before a meeting

Test the endpoint from the Vexa host before sending a bot:
Accept the endpoint only if it returns HTTP 2xx and a non-empty text field. A 404 usually means the base URL already included /v1 or /v1/audio/transcriptions. A 401 or 403 means the token is missing or wrong. A model_not_found response means TRANSCRIPTION_MODEL does not match the served model id.

Keep provider errors attributable

When adding or operating a custom STT backend:
  • Preserve the raw HTTP status in logs.
  • Keep provider error messages sanitized, but do not collapse every failure into “transcription failed”.
  • Separate route errors, auth errors, model-id errors, and audio-format errors.
  • Keep long-audio chunking on the backend side if the model has a fixed window limit.
That makes a bad URL, expired token, unsupported model id, or model-specific audio limit diagnosable without changing the meeting bot.