API reference

Speech-to-text API

A model-neutral HTTP boundary for local Swedish and English transcription. The API accepts complete audio or video files and also exposes endpointed realtime microphone transcription.

Base URLhttp://localhost:8080
Content typemultipart/form-data
CompatibilityOpenAI-style
Language is explicit.

Every transcription request must specify sv or en. Automatic language selection is intentionally unsupported for short utterances.

01

Getting started

Quick start

Download the pinned models, start the stack, then send a multipart request.

shell
cp .env.example .env
bun run models:download
docker compose up --build

curl http://localhost:8080/readyz
curl http://localhost:8080/v1/audio/transcriptions \
  -F file=@recording.wav \
  -F language=sv
02

Discovery

Models

Public aliases stay stable even when the worker implementation changes. Discover them from GET /v1/models. Fast aliases prioritize lower latency with reduced accuracy; small aliases provide higher quality and can be much slower on CPU-only hosts.

SVswedish-small

Swedish transcription routed to the dedicated KB-Whisper worker.

Timestamps
Segment
VAD
Silero 6.2
ENenglish-small

English transcription routed to the dedicated English worker.

Timestamps
Segment
VAD
Silero 6.2
SVswedish-fast

Lower-latency Swedish transcription using the Fast mode.

Mode
Fast
Timestamps
Segment
ENenglish-fast

Lower-latency English transcription using the Fast mode.

Mode
Fast
Timestamps
Segment
03

Operations

Health & readiness

GET/healthz

Process-only liveness. It does not contact model workers.

{"status":"ok"}
GET/readyz

Checks both required workers concurrently. Returns 503 if either worker is unavailable.

{
  "status": "ready",
  "workers": { "sv": "ready", "en": "ready" }
}
04

Core endpoint

Transcriptions

Field Type Required Description
file media file Yes One non-empty WAV, MP3, M4A/MP4, MOV, MKV, FLAC, OGG, or WebM file. Supported video containers are decoded by the worker.
language sv | en Yes Selects the dedicated worker.
model string No Stable alias. If supplied, it must agree with the language.
prompt string No Context or expected vocabulary, up to 1,000 characters.
response_format enum No json, verbose_json, or text. Defaults to JSON.
temperature number No OpenAI-compatible decoding value from 0 to 1.
JavaScript
const form = new FormData();
form.append("file", audioFile);
form.append("language", "en");
form.append("response_format", "verbose_json");

const response = await fetch("/v1/audio/transcriptions", {
  method: "POST",
  body: form,
});

const transcript = await response.json();

Subtitle preview

Studio's Subtitles mode requests verbose_json, turns normalized segments into WebVTT and SRT in the browser, and synchronizes them with the uploaded audio or video. These are Studio exports—not additional API response formats—and captions are not burned into the video.

05

Live audio

Realtime WebSocket

Start the session

{
  "type": "session.start",
  "language": "en",
  "model": "english-small",
  "sample_rate": 48000,
  "temperature": 0
}

After session.ready, send mono signed PCM16 little-endian binary frames. Finish with {"type":"session.stop"}. The gateway drains queued utterances before finalizing.

Server events

session.ready
speech.started
speech.stopped
transcript.partial
transcript.final
session.completed

Partials contain accumulated text and absolute normalized segments. Sessions do not resume after disconnect. Model speed and queueing determine how far transcript updates lag behind speech.

06

Schemas

Responses

JSON

{
  "text": "Hej, hur mår du?",
  "language": "sv",
  "duration": 1.84,
  "model": "swedish-small"
}

Verbose JSON

{
  "text": "Hej, hur mår du?",
  "language": "sv",
  "duration": 1.84,
  "model": "swedish-small",
  "segments": [
    { "id": 0, "start": 0.12, "end": 1.72, "text": "Hej, hur mår du?" }
  ]
}

The text format returns only UTF-8 transcript text with text/plain.

07

Failure contract

Errors

Errors have stable public codes and a request ID. Worker stderr, paths, stack traces, audio, and prompts are never included.

{
  "error": {
    "code": "invalid_language",
    "message": "language must be either sv or en",
    "request_id": "3e80…"
  }
}
invalid_requestinvalid_languageunsupported_media_typefile_too_largeworker_unavailabletranscription_timeouttranscription_failedrate_limited
08

Security

Authentication

Authentication is disabled when API_KEYS is empty. When configured, HTTP /v1/* routes require a Bearer key. Browser realtime clients send the key inside their first session.start message because WebSocket APIs cannot set an Authorization header. Health and readiness remain public.

Authorization: Bearer your-local-key
09

Runtime

Configuration

Variable Default Purpose
PORT 8080 Gateway container port
GATEWAY_PORT 8080 Host port in Compose
WORKER_TIMEOUT_MS 120000 Transcription timeout
READINESS_TIMEOUT_MS 2000 Per-worker readiness timeout
MAX_UPLOAD_BYTES 26214400 Maximum audio upload
API_KEYS empty Comma-separated Bearer keys
WORKER_CONCURRENCY 1 Concurrent inference per worker
WORKER_QUEUE_SIZE 4 Queued requests per worker
REALTIME_MAX_SESSIONS 2 Concurrent realtime connections
REALTIME_MAX_SESSION_MS 120000 Maximum audio duration per live session
REALTIME_MAX_CHUNK_BYTES 65536 Maximum binary WebSocket frame
10

Deployment

Docker Compose

The primary stack contains a Bun gateway and two private, long-lived CPU workers. Only the gateway port is published.

ClientGateway :8080
Swedish workerEnglish worker

Both images build natively for Linux amd64 and arm64. Keep worker ports private and place TLS in front of the gateway for public deployments.

11

Boundaries

Limits & privacy

  • Maximum upload: 25 MB by default.
  • Worker processing window: five minutes. The gateway does not pre-probe decoded duration.
  • Audio and transcripts are processed locally and are not intentionally retained.
  • Logs contain request metadata, never audio, transcript text, prompts, API keys, or authorization headers.
  • Realtime mode is endpointed and has no reconnect/resume protocol. Language auto-detection, diarization, and pronunciation grading are not provided.

Ready to send a real request?

Open Transcription Studio