Audio
The Audio endpoints turn speech into text. audio.transcriptions transcribes audio in its own language. audio.translations (deprecated) transcribes and translates into English. Both are OpenAI-compatible and take a multipart file upload.
Glexir sells speech-to-text only. Text-to-speech and realtime voice are not available.
Transcribe a file
Response:
Supported models
The TranscriptionModel type lists these IDs. It also accepts any other string.
| Model | Notes |
|---|---|
gpt-transcribe | Start here. Supports languages and keywords. |
gpt-4o-transcribe | Shuts down on 2027-02-26. |
gpt-4o-mini-transcribe | Shuts down on 2027-02-26. |
gpt-4o-mini-transcribe-2025-12-15 | Shuts down on 2027-02-26. |
gpt-4o-transcribe-diarize | Speaker labels. Shuts down on 2027-02-26. |
whisper-1 | The only model for translations and verbose_json timestamps. Shuts down on 2027-02-26. |
Only priced models work
A model must also be in Glexir's price book. Today the price book sells gpt-transcribe only, so the other models above return 403 with code model_not_priced. Call models.list() to see what your key can use right now.
File uploads
The request is multipart/form-data. The SDK builds it for you when you pass file.
- The file must be 25 MB or smaller. Larger files return
413with codefile_too_large. Split long recordings into chunks. - Supported formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav and webm.
- The format is detected from the filename, so the upload needs a name with the right extension.
file is an Uploadable: File | Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | Response. Pass a File, or wrap other data with toFile(data, "name.ext"). If you pass a Blob or bytes without a name, the SDK names the part file.bin and the format can't be detected.
toFile()
Wraps data in a File with a filename and an optional MIME type. It throws a GlexirError if no filename is given and data is not already a File. A File passed with no name and no type is returned as-is.
The SDK sends text fields before the file part, writes arrays as repeated key[] parts, and objects as key[sub] parts. You don't need to do anything for this.
Response formats
response_format decides what the call returns. The SDK's return type follows it.
response_format | Returns | Notes |
|---|---|---|
json (default) | Transcription | { text, usage, ... } |
verbose_json | TranscriptionVerbose | Adds duration, language, segments, words. whisper-1 only. |
diarized_json | TranscriptionDiarized | Speaker-labelled segments. gpt-4o-transcribe-diarize only. |
text | string | Plain text. |
srt | string | SubRip subtitles. |
vtt | string | WebVTT subtitles. |
Word and segment timestamps need whisper-1 with response_format: "verbose_json" and timestamp_granularities.
Languages and keywords
With gpt-transcribe, pass candidate languages and domain keywords to improve accuracy. Don't send language and languages together.
Stream a transcript
Set stream: true to get transcript events as they are produced. The call returns a Stream<TranscriptionStreamEvent>.
whisper-1 ignores stream and returns a normal response. See Streaming for Stream methods.
Event type | Type | Fields |
|---|---|---|
transcript.text.delta | TranscriptionTextDeltaEvent | delta, logprobs?, segment_id? (diarization only) |
transcript.text.segment | TranscriptionTextSegmentEvent | id, start, end, speaker, text. Diarize model with diarized_json. |
transcript.text.done | TranscriptionTextDoneEvent | text, languages?, logprobs?, usage? |
Speaker diarization
gpt-4o-transcribe-diarize with response_format: "diarized_json" returns segments labelled by speaker. Name up to four speakers with known_speaker_names and matching known_speaker_references (data: URLs of 2 to 10 second samples). Unnamed speakers are labelled A, B and so on. For audio longer than 30 seconds, chunking_strategy is required.
This model is not in the price book today, so the call returns 403 model_not_priced. The types are documented below for completeness.
Translations (deprecated)
audio.translations.create() transcribes audio and translates it into English. It works with whisper-1 only, and OpenAI shuts down /audio/translations on 2027-02-26. whisper-1 is not in Glexir's price book today, so the call returns 403 model_not_priced. Use audio.transcriptions instead.
response_format works as for transcriptions: json (default) returns Translation ({ text }), verbose_json returns TranslationVerbose (duration, language, text, segments?), and text, srt and vtt return a string.
fileUploadablerequired- The audio file, as for transcriptions.
model"whisper-1" | stringrequired- Only whisper-1.
promptstringoptional- Context for the model. Should be in English.
response_format"json" | "text" | "srt" | "verbose_json" | "vtt"optionaldefault"json"- Output format.
temperaturenumberoptional- Sampling temperature.
Per-second billing
Transcription is billed by audio duration, per second, at the model's per-minute rate divided by 60. Each request is billed at least 1 second, and partial seconds round up. See Pricing for the rate.
Glexir finds the duration in this order:
usage.secondswhen the response has duration usage (json,diarized_json, or the finaltranscript.text.donestream event).durationfrom averbose_jsonresponse.- Otherwise (
text,srt,vtt, or no usage), the duration Glexir reads from the uploaded file. If the file can't be read, it estimates from the file size at about 16 kbit/s.
Before forwarding, Glexir reserves a hold sized from the file's duration (or the size estimate) and settles it when the response or stream ends. See Credits & billing.
Method reference
glexir.audio.transcriptions.create()
POST /audio/transcriptions. The overloads above pick the return type from response_format and stream, as in the Response formats table. options are the per-request options described in Client configuration.
fileUploadablerequired- Audio file, at most 25 MB: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav or webm. Needs a filename with an extension.
modelTranscriptionModelrequired- A speech-to-text model ID. A missing or non-transcription model returns 400 model_not_found.
response_formatAudioResponseFormatoptionaldefault"json"- json, text, srt, verbose_json, vtt or diarized_json.
languagestringoptional- ISO-639-1 code of the audio. With gpt-transcribe, use languages instead (not both).
languagesstring[]optional- Candidate languages (gpt-transcribe). ISO 639-1, some ISO 639-3, and zh-cn, zh-tw, zh-hk.
keywordsstring[]optional- Domain terms to bias recognition (gpt-transcribe). Entries must not contain <, >, CR or LF.
promptstringoptional- Context or a previous transcript, in the audio's language. Not supported by the diarize model.
temperaturenumberoptional- 0 to 1. 0 lets the model pick automatically.
timestamp_granularitiesArray<"word" | "segment">optional- Needs response_format verbose_json (whisper-1 only).
includeArray<"logprobs">optional- logprobs works with json output on the gpt-4o-transcribe models.
chunking_strategy"auto" | VadConfigoptional- Required for the diarize model when audio is longer than 30 seconds.
known_speaker_namesstring[]optional- Up to 4 speaker labels for diarization, for example customer and agent.
known_speaker_referencesstring[]optional- data: URLs of 2 to 10 second samples, in the same order as known_speaker_names.
streamboolean | nulloptional- true returns a Stream of TranscriptionStreamEvent.
Other keys are sent as extra form fields.
type"server_vad"required- Voice activity detection.
prefix_padding_msnumberoptional- Audio to include before detected speech, in milliseconds.
silence_duration_msnumberoptional- Silence that ends a speech segment, in milliseconds.
thresholdnumberoptional- Detection sensitivity, 0.0 to 1.0.
Response types
textstringrequired- The transcript.
languagesArray<{ code: string }>optional- Detected languages (gpt-transcribe). Empty when detection was unreliable.
logprobsTranscriptionLogprob[]optional- With include: ["logprobs"]. Each has token?, bytes?, logprob?.
usageTranscriptionUsageoptional- TranscriptionDurationUsage { type: "duration"; seconds } or TranscriptionTokenUsage { type: "tokens"; input_tokens; output_tokens; total_tokens; input_token_details? }.
_request_idstring | nulloptional- SDK only. The x-request-id header.
durationnumberrequired- Audio length in seconds.
languagestringrequired- Detected language.
textstringrequired- The transcript.
segmentsTranscriptionSegment[]optional- id, seek, start, end, text, tokens, temperature, avg_logprob, compression_ratio, no_speech_prob.
wordsTranscriptionWord[]optional- word, start, end. With timestamp_granularities: ["word"].
usageTranscriptionDurationUsageoptional- Seconds billed.
task"transcribe"required- Always transcribe.
durationnumberrequired- Audio length in seconds.
textstringrequired- The full transcript.
segmentsTranscriptionDiarizedSegment[]required- id, type (transcript.text.segment), start, end, text, speaker. speaker is a known_speaker_names value, otherwise A, B and so on.
usageTranscriptionUsageoptional- Usage for the request.
Errors
| Status | Code | When |
|---|---|---|
| 400 | model_not_found | model is missing or is not a speech-to-text model. |
| 400 | none | The body is not multipart, or file is missing. |
| 402 | credit_balance_exhausted, spend_limit_exceeded | The hold can't be reserved. |
| 403 | model_not_priced | The model is not in the price book. |
| 413 | file_too_large | The file is over 25 MB. |
| 429 | rate_limit_exceeded, concurrency_limit_exceeded | Too many requests per minute, or too many in flight. |
See HTTP error codes for the full list.