Get started
Quickstart
An API key, the SDK, and your first transcript in a dozen lines.
Three steps: create an API key, install an SDK, transcribe a file. The program at the end uploads talk.mp3 (any mp3, wav, flac, ogg, m4a or mp4 works), waits for its job and prints the transcript.
Create an API key
Open Developers → API keys and create a key with the Read and Write permissions. It is shown once: copy it into
VOCALSTACK_API_KEY.A key is for servers and scripts. The API refuses one sent from a web page or in a URL, so never put it in browser code; a browser streams through a session your server creates (see Stream a microphone).
Install an SDK
Two SDKs, one client each (
VocalStack), grouped by resource:vs.transcriptions,vs.jobs,vs.recordings,vs.realtimeand a few more. TypeScript runs on Node 20 or newer and in browsers; Python is asyncio, 3.10 or newer.These commands are this environment's own. While the SDKs are not on npm or PyPI, the API serves its builds to every account, and the commands send your key to this API's host only. With HTTP + WebSocket there is nothing to install: the programs use curl and jq, and Node 22's built-in WebSocket (any WebSocket client works).
Transcribe a file
Transcribing a file is asynchronous: the upload answers at once with a transcription and its job, the job runs on the server, and the transcript is read when the job is done. There are no webhooks:
vs.jobs.waitpolls the job for you (every 2 s by default).Every call is real usage on your plan: the minutes count against its audio quotas, and once the included usage is used up (or for a route your plan doesn't include) the API answers
402(Errors, retries and limits). Transcribe a file covers the job's states, progress and exports.Next
- Transcribe a link: the server fetches a public URL or a YouTube video.
- Stream a microphone: live audio in, transcript events out, over one WebSocket.
- Errors, retries and limits: what to do with a 402, a 429 or a 503.
TypeScript SDK
export VOCALSTACK_API_KEY="<your API key>"
mkdir vocalstack-quickstart && cd vocalstack-quickstart
npm init -y && npm pkg set type=module
echo '//api.vocalstack.com/:_authToken=${VOCALSTACK_API_KEY}' >> .npmrc
npm install https://api.vocalstack.com/sdk/typescript/vocalstack-sdk-1.0.0-alpha.0.dev.20261008174440.gdafcde5.tgz
npm install --save-dev tsx
npx tsx quickstart.ts
import { VocalStack } from '@vocalstack/sdk';
const vs = new VocalStack({ baseUrl: 'https://api.vocalstack.com', apiKey: process.env.VOCALSTACK_API_KEY });
const tx = await vs.transcriptions.create({ file: './talk.mp3' });
const job = await vs.jobs.wait(tx.job!.recordingId); // queued → transcribing → done
if (job.state !== 'done') throw new Error(`transcription ${job.state}: ${job.error ?? ''}`);
const { sentences } = await vs.recordings.transcript(job.recordingId);
for (const s of sentences) console.log(s.text);
Python SDK
export VOCALSTACK_API_KEY="<your API key>"
python3 -m venv .venv && . .venv/bin/activate
pip install "https://__token__:${VOCALSTACK_API_KEY}@api.vocalstack.com/sdk/python/vocalstack-1.0.0a0.dev20261008174440+gdafcde5-py3-none-any.whl"
python quickstart.py
import asyncio
import os
from vocalstack import VocalStack
async def main() -> None:
async with VocalStack("https://api.vocalstack.com", api_key=os.environ["VOCALSTACK_API_KEY"]) as vs:
tx = await vs.transcriptions.create(file="./talk.mp3")
assert tx.job is not None
job = await vs.jobs.wait(tx.job.recording_id) # queued -> transcribing -> done
if job.state != "done":
raise RuntimeError(f"transcription {job.state}: {job.error}")
snapshot = await vs.recordings.transcript(job.recording_id)
for sentence in snapshot.sentences:
print(sentence.text)
asyncio.run(main())
HTTP + WebSocket
#!/usr/bin/env bash
# curl and jq, no SDK.
set -euo pipefail
export VOCALSTACK_API_KEY="${VOCALSTACK_API_KEY:?create a key under Developers → API keys}"
API=https://api.vocalstack.com
AUTH="Authorization: Bearer $VOCALSTACK_API_KEY"
REC=$(curl -sSf "$API/v1/transcriptions" -H "$AUTH" -F file=@talk.mp3 | jq -r .job.recordingId)
until [[ $(curl -sSf "$API/v1/recordings/$REC/job" -H "$AUTH" | jq -r .state) =~ ^(done|failed)$ ]]; do
sleep 2
done
curl -sSf "$API/v1/recordings/$REC/transcript" -H "$AUTH" | jq -r '.sentences[].text'