Transcribe a file
POST /v1/audio/transcriptions takes a multipart upload of an audio file and a model, and returns the transcript.
The request shape is OpenAI's, so OpenAI SDKs work with the base URL changed. The example makes a clip with Kokoro,
then transcribes the clip with Parakeet.
curl
curl https://api.albastov.com/v1/audio/speech \
-H "Authorization: Bearer $ALBASTOV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kokoro", "voice": "af_heart", "input": "The river bends past the old mill."}' \
--output river.mp3
curl https://api.albastov.com/v1/audio/transcriptions \
-H "Authorization: Bearer $ALBASTOV_API_KEY" \
-F model=parakeet \
-F [email protected]Python
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.albastov.com/v1", api_key=os.environ["ALBASTOV_API_KEY"])
with client.audio.speech.with_streaming_response.create(
model="kokoro", voice="af_heart", input="The river bends past the old mill."
) as res:
res.stream_to_file("river.mp3")
with open("river.mp3", "rb") as f:
print(client.audio.transcriptions.create(model="parakeet", file=f).text)JavaScript
const base = "https://api.albastov.com/v1";
const auth = { Authorization: `Bearer ${process.env.ALBASTOV_API_KEY}` };
const speech = await fetch(`${base}/audio/speech`, {
method: "POST",
headers: { ...auth, "Content-Type": "application/json" },
body: JSON.stringify({ model: "kokoro", voice: "af_heart", input: "The river bends past the old mill." }),
});
if (!speech.ok) throw new Error(`${speech.status} ${await speech.text()}`);
const form = new FormData();
form.append("model", "parakeet");
form.append("file", await speech.blob(), "river.mp3");
const res = await fetch(`${base}/audio/transcriptions`, { method: "POST", headers: auth, body: form });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log((await res.json()).text);{"text": "The river bends past the old mill."}The file is WAV, MP3, M4A, Ogg, WebM or FLAC, 20 MB at most. The key needs the media:generate scope.
Pick a model
| Need | Model |
|---|---|
| Transcripts with punctuation in 25 European languages | Parakeet |
Parakeet detects the language itself; language is a hint. A sample transcript: Audio models.
Word timestamps
response_format=verbose_json returns the transcript with timings. timestamp_granularities[] picks segment
(the default), word, or both.
curl
curl https://api.albastov.com/v1/audio/speech \
-H "Authorization: Bearer $ALBASTOV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kokoro", "voice": "af_heart", "input": "The river bends past the old mill."}' \
--output river.mp3
curl https://api.albastov.com/v1/audio/transcriptions \
-H "Authorization: Bearer $ALBASTOV_API_KEY" \
-F model=parakeet \
-F [email protected] \
-F response_format=verbose_json \
-F "timestamp_granularities[]=word"Python
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.albastov.com/v1", api_key=os.environ["ALBASTOV_API_KEY"])
with client.audio.speech.with_streaming_response.create(
model="kokoro", voice="af_heart", input="The river bends past the old mill."
) as res:
res.stream_to_file("river.mp3")
with open("river.mp3", "rb") as f:
t = client.audio.transcriptions.create(
model="parakeet", file=f, response_format="verbose_json", timestamp_granularities=["word"]
)
for w in t.words:
print(f"{w.start:6.2f} {w.end:6.2f} {w.word}"){
"task": "transcribe",
"language": "en",
"duration": 2.36,
"text": "The river bends past the old mill.",
"words": [
{"word": "The", "start": 0, "end": 0.24},
{"word": "river", "start": 0.24, "end": 0.56}
]
}The words list above is shortened to two entries. With segment, segments lists each segment with start,
end and text.
Response formats
response_format | Content type | Body |
|---|---|---|
json | application/json | {"text": "..."}; the default |
text | text/plain | The transcript and a newline |
verbose_json | application/json | task, language, duration, text, and segments or words |
OpenAI model name
whisper-1 runs as parakeet, so code written for OpenAI transcribes without changes. prompt and temperature
are accepted and ignored; stream takes false only, because the transcript arrives whole.
Transcription jobs
POST /v1/media/jobs with kind transcription transcribes a file already on the account, or an https:// URL,
without a second upload. params.audio takes an upload up_…, a job result job:<id>/<i>, a saved voice vo_… or
an https:// URL; params.timestamps true adds word timings. The result entry carries the whole transcript in
text. The example transcribes the clip of the shared voice vo_hVAiUiqrYyvgKKkBvgzHnh.
curl
curl "https://api.albastov.com/v1/media/jobs?wait=30" \
-H "Authorization: Bearer $ALBASTOV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind": "transcription", "model": "parakeet", "params": {"audio": "vo_hVAiUiqrYyvgKKkBvgzHnh"}}'A transcription waits in the queue up to its queue_timeout_s, 60 s by default. On
POST /v1/audio/transcriptions, a job not done in time answers 503 with code queued and job_id, as on the
speech route: Waiting for a result.
Reference
- Transcriptions reference: every parameter, header and
error of
POST /v1/audio/transcriptions. - Media jobs reference: transcription jobs and
?wait.